首页 > 解决方案 > geom_density 返回图而不考虑实际值

问题描述

我正在尝试为 7 个不同地理点上的 3 个变量绘制密度图,但输出未按预期显示。N应该在中间更高,但另一个似乎在它不真实时绘制相同的模式,这是为什么呢?我该如何解决?

Variable1 <- c(rep("E",7), rep("N",7),rep("L",7))
Variable2 <- c(rep(1:7, 3))
value <- c(12.44035, 11.98035333, 11.40821, 12.15833, 13.14826, 11.99339667, 12.17363, 4.073096, 3.946134667, 6.244152, 5.76892, 4.545772, 3.580206667, 2.879470667, 3.6912875, 3.501247, 2.684179, 3.06306, 3.364774, 4.485021333, 3.373649333)
df <- data.frame(Variable1, Variable2, value)

library(ggridges)
ggplot(df, aes(x = Variable2, y = Variable1)) +
  geom_density_ridges(aes(fill = Variable1)) 

在此处输入图像描述

我想要这样的东西: 在此处输入图像描述

标签: rggplot2density-plot

解决方案


您正在计算 x 轴的密度,在您的情况下是Variable 2,每个 都是相同的东西 ( 1,2,...,7) Variable 1,所以它给出了相同的密度。

所以我认为你希望你的 x 轴是value,而你实际上并不需要Variable 2,因为它只是一个索引。

ggplot(df, aes(x=value, y=Variable1)) +
  geom_density_ridges(aes(fill=Variable1)) 

在此处输入图像描述

编辑1:

您实际上想要的几何图形是geom_line, 或geom_smooth(用于更漂亮的图形),或者可能geom_area用于填充曲线下的区域。

现在,一种方法是将所有曲线放在相同的 y 刻度上:

ggplot(df, aes(x=Variable2, y=value, color=Variable1)) +
  geom_smooth(fill=NA)

在此处输入图像描述

但这并没有给出你想要的分离。要做到这一点,我知道的方式是为每个人制作一个情节Variable1,并将它们安排在一起(但也许这个包有一个选项ggridges,但我从未使用过它)。为此,我们构建了一个“基础”图:

g = ggplot(df, aes(x=Variable2, y=value)) +
  geom_smooth(fill=NA) +
  theme(axis.text.x  = element_blank(),
        axis.title.x = element_blank())

我们删除了 x 轴以在网格中仅添加一次。然后,我们为每个变量应用该基础,一次一个,使用 for 循环:

for(i in unique(df$Variable1)){
  df2 = df[df$Variable1==i,]
  assign(i,
         g %+% df2 + ylab(i) +
               ylim(min(df2$value),max(df2$value)))}

这将为每个创建一个图形Variable1,命名为变量本身。现在我们在最后一个图中添加 x 轴并将它们排列在一起:

N = N + theme(axis.text.x  = element_text(),
              axis.title.x = element_text())

gridExtra::grid.arrange(E,L,N, nrow=3)

输出:

在此处输入图像描述

编辑2:

要使用颜色,首先我们不传递geomto g

g = ggplot(df, aes(x=Variable2, y=value)) +
  theme(axis.text.x  = element_blank(),
        axis.title.x = element_blank())

然后我们创建一个我们将在循环中使用的颜色向量:

color = c("red", "green", "blue")
names(color) = unique(df$Variable1)

然后我们在我们之前省略的内部传递color参数。geom

但首先,让我谈谈可用的几何图形:我们可以使用一个平滑的几何图形区域,它会给出这样的结果:

在此处输入图像描述

这很好,但在图表下有很多无用的区域。为了改变这一点,我们可以使用geom_ribbon,我们可以使用参数aes(ymin=min(value)-0.1, ymax=value)ylim(min(df2$value)-0.1, max(df2$value))在最小值(负 0.1)处停止图形。问题是 ggplot 的平滑函数不能很好地与 geom_ribbon 一起使用,所以我们只有“粗糙”图的选项:

在此处输入图像描述

smoot 区域的代码:

for(i in unique(df$Variable1)){
  df2 = df[df$Variable1==i,]
  assign(i,
         g %+% df2 + ylab(i) +
         stat_smooth(geom="area", fill=color[i]))}

粗丝带代码:

for(i in unique(df$Variable1)){
  df2 = df[df$Variable1==i,]
  assign(i,
         g %+% df2 + ylab(i) + ylim(min(df2$value)-0.1,max(df2$value)) +
         geom_ribbon(aes(ymax=value, ymin=min(value)-0.1), fill=color[i]))}

我寻找了一种解决这个问题的方法,但什么也没找到,我会在网站上创建一个问题,如果我找到解决方案,我会在这里展示!

编辑 3:

这里询问后,我发现在参数after_stat内部使用解决了它(更多信息阅读链接)。aesstat_smooth(geom="ribbon", aes(...))

for(i in unique(df$Variable1)){
  df2 = df[df$Variable1==i,]
  assign(i,
         g %+% df2 + ylab(i) + 
           stat_smooth(geom="ribbon", fill=color[i],
                       aes(ymax=after_stat(value), ymin=after_stat(min(value))-0.1)))}

在此处输入图像描述


推荐阅读