R ggplot2中带有边缘直方图的散点图
是否有一种方法可以创建带有边缘直方图的散点图,就像下面R ggplot2中带有边缘直方图的散点图,r,ggplot2,histogram,scatter-plot,R,Ggplot2,Histogram,Scatter Plot,是否有一种方法可以创建带有边缘直方图的散点图,就像下面ggplot2中的示例一样?在Matlab中,它是scatterhist()函数,并且存在R的等价物。然而,我已经有好几年没有看到它了 我开始尝试创建单个图形,但不知道如何正确排列它们 require(ggplot2) x<-rnorm(300) y<-rt(300,df=2) xy<-data.frame(x,y) xhist <- qplot(x, geom="histogram") + sca
ggplot2
中的示例一样?在Matlab中,它是scatterhist()
函数,并且存在R的等价物。然而,我已经有好几年没有看到它了
我开始尝试创建单个图形,但不知道如何正确排列它们
require(ggplot2)
x<-rnorm(300)
y<-rt(300,df=2)
xy<-data.frame(x,y)
xhist <- qplot(x, geom="histogram") + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 5/16, axis.text.y = theme_blank(), axis.title.y=theme_blank(), background.colour="white")
yhist <- qplot(y, geom="histogram") + coord_flip() + opts(background.fill = "white", background.color ="black")
yhist <- yhist + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 16/5, axis.text.y = theme_blank(), axis.title.y=theme_blank() )
scatter <- qplot(x,y, data=xy) + scale_x_continuous(limits=c(min(x),max(x))) + scale_y_continuous(limits=c(min(y),max(y)))
none <- qplot(x,y, data=xy) + geom_blank()
require(ggplot2)
这不是一个完全响应的答案,但它非常简单。它说明了显示边缘密度的另一种方法,以及如何使用alpha级别进行支持透明度的图形输出:
scatter <- qplot(x,y, data=xy) +
scale_x_continuous(limits=c(min(x),max(x))) +
scale_y_continuous(limits=c(min(y),max(y))) +
geom_rug(col=rgb(.5,0,0,alpha=.2))
scatter
scattergridExtra
包应该在这里工作。首先制作每个ggplot对象:
hist_top <- ggplot()+geom_histogram(aes(rnorm(100)))
empty <- ggplot()+geom_point(aes(1,1), colour="white")+
theme(axis.ticks=element_blank(),
panel.background=element_blank(),
axis.text.x=element_blank(), axis.text.y=element_blank(),
axis.title.x=element_blank(), axis.title.y=element_blank())
scatter <- ggplot()+geom_point(aes(rnorm(100), rnorm(100)))
hist_right <- ggplot()+geom_histogram(aes(rnorm(100)))+coord_flip()
增加一项,只是为了节省一些搜索时间,让人们在我们之后进行搜索
图例、轴标签、轴文本、记号会使绘图相互偏离,因此您的绘图看起来丑陋且不一致
您可以使用这些主题设置中的一些来更正此问题
+theme(legend.position = "none",
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
plot.margin = unit(c(3,-5.5,4,3), "mm"))
并对齐刻度
+scale_x_continuous(breaks = 0:6,
limits = c(0,6),
expand = c(.05,.05))
所以结果看起来不错:
根据边际分布指标的一般精神,这只是一个非常微小的变化
将rug图的这种使用称为“点划线图”,并且在VDQI中有一个使用轴线指示每个变量范围的示例。在我的示例中,轴标签和网格线还指示数据的分布。标签位于(最小值、下铰链、中间值、上铰链、最大值)的值处,可快速显示每个变量的分布情况
因此,这五个数字是箱线图的数字表示。这有点棘手,因为间距不均匀的网格线表明轴具有非线性比例(在本例中,它们是线性的)。也许最好省略网格线或强制它们位于常规位置,让标签显示五个数字的摘要
x<-rnorm(300)
y<-rt(300,df=10)
xy<-data.frame(x,y)
require(ggplot2); require(grid)
# make the basic plot object
ggplot(xy, aes(x, y)) +
# set the locations of the x-axis labels as Tukey's five numbers
scale_x_continuous(limit=c(min(x), max(x)),
breaks=round(fivenum(x),1)) +
# ditto for y-axis labels
scale_y_continuous(limit=c(min(y), max(y)),
breaks=round(fivenum(y),1)) +
# specify points
geom_point() +
# specify that we want the rug plot
geom_rug(size=0.1) +
# improve the data/ink ratio
theme_set(theme_minimal(base_size = 18))
x这可能有点晚了,但我决定为此制作一个包(ggExtra
),因为它涉及一些代码,编写起来可能会很乏味。该软件包还试图解决一些常见问题,例如确保即使有标题或文本被放大,情节仍将相互关联
基本思想与这里给出的答案相似,但有点超出了这个范围。下面是一个如何将边缘直方图添加到1000个点的随机集合的示例。希望这能使将来添加直方图/密度图变得更容易
库(ggplot2)
df因为在比较不同的组时,这种图没有令人满意的解决方案,所以我写了一篇文章来做这件事
它适用于分组和非分组数据,并接受其他图形参数:
marginal_plot(x = iris$Sepal.Width, y = iris$Sepal.Length)
我发现这个包(ggpubr
)似乎很适合这个问题,它考虑了几种显示数据的可能性
该软件包的链接是,在中,您将找到一个很好的教程来使用它。为了完整起见,我附上一个我复制的例子
我首先安装了该软件包(它需要devtools
)
对于为不同组显示不同直方图的特定示例,它提到了与ggExtra
相关的内容:“ggExtra
的一个限制是它不能处理散点图和边缘图中的多个组。在下面的R代码中,我们提供了一个使用cowplot
包的解决方案。”就我而言,我必须安装后一个软件包:
install.packages("cowplot")
我遵循这段代码:
# Scatter plot colored by groups ("Species")
sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
color = "Species", palette = "jco",
size = 3, alpha = 0.6)+
border()
# Marginal density plot of x (top panel) and y (right panel)
xplot <- ggdensity(iris, "Sepal.Length", fill = "Species",
palette = "jco")
yplot <- ggdensity(iris, "Sepal.Width", fill = "Species",
palette = "jco")+
rotate()
# Cleaning the plots
sp <- sp + rremove("legend")
yplot <- yplot + clean_theme() + rremove("legend")
xplot <- xplot + clean_theme() + rremove("legend")
# Arranging the plot using cowplot
library(cowplot)
plot_grid(xplot, NULL, sp, yplot, ncol = 2, align = "hv",
rel_widths = c(2, 1), rel_heights = c(1, 2))
#按组(“物种”)着色的散点图
sp您可以使用以下方法轻松创建有吸引力的散点图,其中包括边缘直方图(它还将拟合和描述模型):
或稍具吸引力(默认情况下):
更新:
正如@aickley所建议的,我使用了发展版来创建绘图。您可以使用互动形式的ggExtra::ggMarginalGadget(yourplot)
,在方块图、小提琴图、密度图和直方图之间轻松选择
如今,至少有一个CRAN软件包可以制作带有边缘直方图的散点图
library(psych)
scatterHist(rnorm(1000), runif(1000))
以@alf pascu的答案为基础,手动设置每个绘图,并使用cowplot
对其进行排列,这为主要绘图和边缘绘图提供了很大的灵活性(与其他一些解决方案相比)。分组分布就是一个例子。将主图更改为二维密度图是另一种方法
下面创建一个带有(正确对齐)边缘直方图的散点图
library(psych)
scatterHist(rnorm(1000), runif(1000))
库(“ggplot2”)
库(“cowplot”)
#建立散点图
散点图使用ggpubr
和cowplot
的另一种解决方案,但这里我们使用cowplot::axis_canvas
创建图,并使用cowplot::insert_xaxis_grob
将它们添加到原始图中:
library(cowplot)
library(ggpubr)
# Create main plot
plot_main <- ggplot(faithful, aes(eruptions, waiting)) +
geom_point()
# Create marginal plots
# Use geom_density/histogram for whatever you plotted on x/y axis
plot_x <- axis_canvas(plot_main, axis = "x") +
geom_density(aes(eruptions), faithful)
plot_y <- axis_canvas(plot_main, axis = "y", coord_flip = TRUE) +
geom_density(aes(waiting), faithful) +
coord_flip()
# Combine all plots into one
plot_final <- insert_xaxis_grob(plot_main, plot_x, position = "top")
plot_final <- insert_yaxis_grob(plot_final, plot_y, position = "right")
ggdraw(plot_final)
库(cowplot)
图书馆(ggpubr)
#创建主情节
plot_main这是一个老问题,但我认为在这里发布更新会很有用,因为我最近遇到了同样的问题(感谢Stefanie Mueller的帮助!)
使用gridExtra是投票最多的答案,但正如评论中所指出的,对齐轴是困难的。现在可以使用ggExtra包中的命令ggMarginal解决此问题,如下所示:
#load packages
library(tidyverse) #for creating dummy dataset only
library(ggExtra)
#create dummy data
a = round(rnorm(1000,mean=10,sd=6),digits=0)
b = runif(1000,min=1.0,max=1.6)*a
b = b+runif(1000,min=9,max=15)
DummyData <- data.frame(var1 = b, var2 = a) %>%
filter(var1 > 0 & var2 > 0)
#plot
p = ggplot(DummyData, aes(var1, var2)) + geom_point(alpha=0.3)
ggMarginal(p, type = "histogram")
#加载包
库(tidyverse)#仅用于创建虚拟数据集
图书馆(ggExtra)
#创建虚拟数据
a=圆形(rnorm(1000,平均值=10,标准差=6),数字=0)
b=运行条件(1000,最小值=1.0,最大值=1.6)*a
b=b+runif(1000,最小值=9,最大值=15)
DummyData%
过滤器(var1>0&var2>0)
#密谋
p=ggplot(DummyData,aes(var1,var2))+geom_点(alpha=0.3)
GG边际(p,type=“直方图”)
我尝试了这些选择,但对结果或混乱不满意
data(iris)
library(ggstatsplot)
ggscatterstats(
data = iris,
x = Sepal.Length,
y = Sepal.Width,
xlab = "Sepal Length",
ylab = "Sepal Width",
marginal = TRUE,
marginal.type = "histogram",
centrality.para = "mean",
margins = "both",
title = "Relationship between Sepal Length and Sepal Width",
messages = FALSE
)
devtools::install_github("kassambara/ggpubr")
library(ggpubr)
ggscatterhist(
iris, x = "Sepal.Length", y = "Sepal.Width",
color = "Species", # comment out this and last line to remove the split by species
margin.plot = "histogram", # I'd suggest removing this line to get density plots
margin.params = list(fill = "Species", color = "black", size = 0.2)
)
library(psych)
scatterHist(rnorm(1000), runif(1000))
library(cowplot)
library(ggpubr)
# Create main plot
plot_main <- ggplot(faithful, aes(eruptions, waiting)) +
geom_point()
# Create marginal plots
# Use geom_density/histogram for whatever you plotted on x/y axis
plot_x <- axis_canvas(plot_main, axis = "x") +
geom_density(aes(eruptions), faithful)
plot_y <- axis_canvas(plot_main, axis = "y", coord_flip = TRUE) +
geom_density(aes(waiting), faithful) +
coord_flip()
# Combine all plots into one
plot_final <- insert_xaxis_grob(plot_main, plot_x, position = "top")
plot_final <- insert_yaxis_grob(plot_final, plot_y, position = "right")
ggdraw(plot_final)
#load packages
library(tidyverse) #for creating dummy dataset only
library(ggExtra)
#create dummy data
a = round(rnorm(1000,mean=10,sd=6),digits=0)
b = runif(1000,min=1.0,max=1.6)*a
b = b+runif(1000,min=9,max=15)
DummyData <- data.frame(var1 = b, var2 = a) %>%
filter(var1 > 0 & var2 > 0)
#plot
p = ggplot(DummyData, aes(var1, var2)) + geom_point(alpha=0.3)
ggMarginal(p, type = "histogram")