ggplot2:添加描述散点图两个维度的条件密度曲线

时间:2015-07-01 18:27:50

标签: r plot ggplot2

我有来自两个类别的2D数据的散点图。我想为每个维度添加密度线 - 不在图表之外(参见Scatterplot with marginal histograms in ggplot2),而是在绘图表面上。我可以为x轴维度得到这个,如下所示:

set.seed(123)
dim1 <- c(rnorm(100, mean=1), rnorm(100, mean=4))
dim2 <- rnorm(200, mean=1)
cat <- factor(c(rep("a", 100), rep("b", 100)))
mydf <- data.frame(cbind(dim2, dim1, cat))
ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
  geom_point() +
  stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
  position="identity", geom="line")

看起来像这样:

enter image description here

但我想要一对垂直运行的类似密度曲线,显示y维中点的分布。我试过了

stat_density(aes(y=dim2, x=0+(..scaled..))), position="identity", geom="line)

但收到错误“stat_density需要以下缺少美学:x”。

有什么想法吗?感谢

3 个答案:

答案 0 :(得分:9)

您可以获得dim2变量的密度。然后,翻转轴并将它们存储在新的data.frame中。之后,它只是将它们绘制在另一个图形之上。

p <- ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
  geom_point() +
  stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
               position="identity", geom="line")

stuff <- ggplot_build(p)
xrange <- stuff[[2]]$ranges[[1]]$x.range  # extract the x range, to make the new densities align with y-axis

## Get densities of dim2
ds <- do.call(rbind, lapply(unique(mydf$cat), function(lev) {
    dens <- with(mydf, density(dim2[cat==lev]))
    data.frame(x=dens$y+xrange[1], y=dens$x, cat=lev)
}))

p + geom_path(data=ds, aes(x=x, y=y, color=factor(cat)))

enter image description here

答案 1 :(得分:2)

到目前为止,我可以制作:

distrib_horiz <- stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
                              position="identity", geom="line")

ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
  geom_point() + distrib_horiz

enter image description here

并且:

distrib_vert <- stat_density(data=mydf, aes(x=dim2, y=(-2+(..scaled..))), 
                             position="identity", geom="line") 

ggplot(data=mydf, aes(x=dim2, y=dim1, colour=as.factor(cat))) + 
  geom_point() + distrib_vert + coord_flip()

enter image description here

但结合它们证明是棘手的。

答案 2 :(得分:1)

到目前为止,我只有一个部分解决方案,因为我没有设法为每个单独的类别获取垂直stat_density行,仅针对总集合。也许这可以作为寻找更好解决方案的起点。我的建议是尝试使用ggMarginal()包中的ggExtra函数。

p <- ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
  geom_point() + stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
           position="identity", geom="line")
library(ggExtra)
ggMarginal(p,type = "density", margins = "y", size = 4)

这是我获得的: enter image description here

我知道它并不完美,但也许这是朝着有益的方向迈出的一步。至少我希望如此。期待看到其他答案。