ggplot2:geom_ribbon 的填充颜色行为

Posted

技术标签:

【中文标题】ggplot2:geom_ribbon 的填充颜色行为【英文标题】:ggplot2: fill color behaviour of geom_ribbon 【发布时间】:2016-09-13 15:33:46 【问题描述】:

我正在尝试在 ggplot2 中为色带着色。使用 geom_ribbon 时,我可以指定 ymin 和 ymax 以及填充颜色。它现在所做的是为 ymin 和 ymax 之间的所有内容着色,而不考虑上限或下限。

示例(改编自互联网):

library("ggplot2")
# Generate data (level2 == level1)
huron <- data.frame(year = 1875:1972, level = as.vector(LakeHuron), level2 = as.vector(LakeHuron))

# Change Level2
huron[1:50,2] <- huron[1:50,2]+100
huron[50:90,2] <- huron[50:90,2]-100

h <- ggplot(huron, aes(year))

h +
  geom_ribbon(aes(ymin = level, ymax = level2), fill = "grey80") +
  geom_line(aes(y = level)) + geom_line(aes(y=level2))

将生成此图表:

我想用与 where (ymin ymax) 的区域。在我的真实数据中,我有导出和导入值。在那里,我想将出口高于进口的区域涂成绿色,进口大于出口的区域我希望功能区为红色。

替代方案:我希望 geom_ribbon 仅填充 ymax > ymin 的区域。

有人知道这是怎么做到的吗?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

不需要手动创建另一列的选项是在 aes(fill = 本身内执行逻辑;

## fill dependent on level > level2
h + 
  geom_ribbon(aes(ymin = level, ymax = level2, fill = level > level2)) +
  geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
  scale_fill_manual(values=c("red", "green"), name="fill")

或者,如果您只想根据该条件为真进行填充,

## fill dependent on level > level2, no fill otherwise
h + 
  geom_ribbon(aes(ymin = level, ymax = level2, fill = ifelse(level > level2, TRUE, NA))) +
  geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
  scale_fill_manual(values=c("green"), name="fill")

我认为缺少内插填充似乎与ggplot2 版本有关,因为@beetroot 的代码也发生了同样的事情

## @beetroot's answer
huron$id <- 1:nrow(huron)
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year))
h +
  geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) +
  geom_line(aes(y = level)) + geom_line(aes(y = level2))    

aes(fill = 中运行没有逻辑的代码时,我得到了@ManuK 的图像输出。

【讨论】:

哇,太好了,非常感谢!这正是我想要的,因为我基本上可以将条件放入'fill ='。但是,我将保留我的更改请求,因为它并不完美:填充不能完美地应用于交叉点。 (这次对我来说没问题)另外,我还是觉得ggplot2中的填充逻辑需要改一下。 超级有帮助!有没有办法用长格式的数据来达到同样的效果?例如,您的数据设置为:年份、级别(1 或 2)、值。我可以做到: h + geom_line(aes(y=Value, group=Level) 但我不知道如何使用这种结构添加 geom_ribbon() 层。 不容易,我不认为。 ggplot2 需要列,因此您需要有一列用作 yminymax 值。不过,将您的长数据tidyr::spread() 转换为所需的格式相当简单。 啊好吧 - 我希望我可以避免更改格式,但就这样吧。谢谢乔诺!【参考方案2】:

您可以将分组变量添加到可用于指定填充颜色的数据中。但是,问题在于两条线的相交点,因为它需要包含在两组中以防止出现任何间隙。

所以先找到这一行..

huron[huron$level == huron$level2,]

> huron[huron$level == huron$level2,]
     year  level level2 
50   1924 577.79 577.79 
...

并再次将其添加到数据中:

huron <- rbind(huron, huron[huron$year == 1924,])
huron <- huron[order(huron$year),]

然后根据行索引添加一个id列,根据1924年的行号设置分组:

huron$id <- 1:nrow(huron)
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year))
h +
  geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) +
  geom_line(aes(y = level)) + geom_line(aes(y = level2))

【讨论】:

非常感谢您的回答,这行得通。但是在我的用例中,由于以下问题,它不是很有用: 1. 我想添加多个功能区,所以我需要添加很多“解决方法”列。 2. 线相交的点在数据中并不真正可见,因此我需要计算这些点并添加到数据库中(两次)。我希望有一个简单的解决方案,但它似乎比简单的条件填充更复杂。 :-) @ManuK 是的,尤其是 2. 据我所知,问题很难解决,不幸的是,我目前无法为您提供帮助。但也许其他人会想出另一个答案?或许this博文能给你一些想法 我将问题作为功能请求提交给 ggplot2 github。我希望它会在 ggplot2 link to request的未来版本中实现@【参考方案3】:

解决我在使用非插值 fill 时遇到的问题,您可以使用两个(或 n)色带

h <- ggplot() +
  geom_ribbon(data = huron[huron$level >= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="green") +
  geom_ribbon(data = huron[huron$level <= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="red") +
  geom_line(data = huron, aes(x = year, y = level)) + 
  geom_line(data = huron, aes(x = year, y = level2))
h

您在aes(fill = 中使用的任何条件都会将其强制为一个因子,因此它似乎只适用于数据实际所在的位置。我不认为这是 ggplot2 错误,我认为这是预期的行为。

【讨论】:

以上是关于ggplot2:geom_ribbon 的填充颜色行为的主要内容,如果未能解决你的问题,请参考以下文章

r语言cox怎么填充置信区间的颜色

如何在 ggplot2 中使用 geom_ribbon 为 geom_hline 制作错误栏?

R语言ggplot2可视化使用geom_ribbon()函数向ggplot2图添加置信度带(Confidence BandConfidence Interval)

ggplot2:图例混合颜色和隐藏线用于预测图

R语言生成数据及其95%置信区间数据(或者其它区间)使用geom_ribbon函数为ggplot2图像手动添加置信区间的阴影区域using geom_ribbon to create shaded

如何设置 ggplot2 填充颜色以聚合统计信息?