【问题标题】:Specifying the scale for the density in ggplot2's stat_density2d在 ggplot2 的 stat_density2d 中指定密度的比例
【发布时间】:2014-09-10 19:27:13
【问题描述】:

我希望创建多个密度图,以制作“动画热图”。

由于动画的每一帧都应该具有可比性,因此我希望每个图表上的密度 -> 颜色映射对于所有人来说都是相同的,即使每个图表的数据范围都发生了变化。

这是我用于每个单独图表的代码:

ggplot(data= this_df, aes(x=X, y=Y) ) + 
    geom_point(aes(color= as.factor(condition)), alpha= .25) +
    coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() +
    stat_density2d(mapping= aes(alpha = ..level..), geom="polygon", bins=3, size=1)

想象一下,我使用相同的代码,但“this_df”在每一帧上都发生了变化。所以在一张图中,密度范围可能从 0 到 4e-4。另一方面,密度范围从 0 到 4e-2。

默认情况下,ggplot 会为每一个计算不同的密度 -> 颜色映射。但这意味着这两个图表——动画的两帧——并没有真正的可比性。如果这是直方图或密度图,我只需调用 coord_cartesian 并更改 x 和 y 限制。但是对于密度图,我不知道如何更改比例。

我能找到的最接近的是:

Overlay two ggplot2 stat_density2d plots with alpha channels

但我没有将两个密度图放在同一张图上的选项,因为我希望它们是不同的帧。

任何帮助将不胜感激!

编辑:

这是一个可重现的例子:

set.seed(4)
g = list(NA,NA)
for (i in 1:2) {

  sdev = runif(1)
  X = rnorm(1000, mean = 512, sd= 300*sdev)
  Y = rnorm(1000, mean = 384, sd= 200*sdev)

  this_df = as.data.frame( cbind(X = X,Y = Y, condition = 1:2) )

  g[[i]] = ggplot(data= this_df, aes(x=X, y=Y) ) + 
    geom_point(aes(color= as.factor(condition)), alpha= .25) +
    coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() +
    stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)), geom="contour", bins=4, size= 2) 

}
print(g) # level has a different scale for each

【问题讨论】:

  • 您将alpha 映射到关卡,而不是颜色。您可以通过添加 scale_alpha_continuous(limits=...) 来控制 alpha 比例,其中 limits 是一个向量,以 ..level.. 为单位指定限制,所以我想是 (0,4e-2)。如果您提供数据集,可能有人愿意为您提供更多帮助。
  • 感谢您的回复!我添加了带有假数据的可重现代码(无法共享真实数据)。请注意,如果您在此代码的末尾添加 + scale_alpha_continuous(limits= c(0, 2e-6)),它会使 alpha 缩放连续,但不会修复轮廓。如何使两个图形的轮廓缩放一致?
  • 您是说要在两个图中为 ..level.. 的相同值绘制等高线吗?如果是这样,那么在stat_density2d(...) 中使用breaks=...

标签: r plot ggplot2 kernel-density


【解决方案1】:

我想为这个问题留下更新。截至 2016 年 7 月,stat_density2d 不再使用breaks。为了重现图形,您需要将breaks=1e-6*seq(0,10,by=2) 移动到scale_alpha_continuous()

set.seed(4)
g = list(NA,NA)
for (i in 1:2) {
    sdev = runif(1)
    X = rnorm(1000, mean = 512, sd= 300*sdev)
    Y = rnorm(1000, mean = 384, sd= 200*sdev)
    this_df = as.data.frame( cbind(X = X,Y = Y, condition = 1:2) )

g[[i]] = ggplot(data= this_df, aes(x=X, y=Y) ) +
         geom_point(aes(color= as.factor(condition)), alpha= .25) +
         coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) +
         scale_y_reverse() +
         stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)),
         geom="contour", bins=4, size= 2) +
         scale_alpha_continuous(limits=c(0,1e-5), breaks=1e-6*seq(0,10,by=2))+
         scale_color_discrete("Condition")
    }

do.call(grid.arrange,c(g,ncol=2))

【讨论】:

    【解决方案2】:

    所以要让两个图都显示具有相同水平的等高线,请使用stat_densit2d(...) 中的breaks=... 参数。要使两个图都具有相同的 alpha 到级别映射,请使用 scale_alpha_continuous(limits=...)

    下面是完整的演示代码:

    library(ggplot2)
    set.seed(4)
    g = list(NA,NA)
    for (i in 1:2) {
      sdev = runif(1)
      X = rnorm(1000, mean = 512, sd= 300*sdev)
      Y = rnorm(1000, mean = 384, sd= 200*sdev)
      this_df = as.data.frame( cbind(X = X,Y = Y, condition = 1:2) )
    
      g[[i]] = ggplot(data= this_df, aes(x=X, y=Y) ) + 
        geom_point(aes(color= as.factor(condition)), alpha= .25) +
        coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() +
        stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)), 
                       breaks=1e-6*seq(0,10,by=2),geom="contour", bins=4, size= 2)+
        scale_alpha_continuous(limits=c(0,1e-5))+
        scale_color_discrete("Condition")
    }
    library(gridExtra)
    do.call(grid.arrange,c(g,ncol=2))
    

    结果……

    【讨论】:

    • 这是我今天需要的解决方案。我运行了代码,发现stat_density2d 没有将breaks 与当前的ggplot2 (ggplot2_2.1.0) 一起使用。你能想出其他方法来达到同样的效果吗?
    • 是否可以在 stat_density 函数之外的其他地方分配您自己的计算密度并在 ggplot 中使用它?
    猜你喜欢
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多