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")