首页 文章

ggplot2:填充geom_ribbon的颜色行为

提问于
浏览
12

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

示例(从Internet修改):

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

将导致此图表:
enter image description here

我想用不同于(ymin <ymax)的颜色填充该区域,其中(ymin> ymax) . 在我的真实数据中,我有导出和导入值 . 在那里,我想为导出高于导入绿色的区域着色,其中导入大于导出我希望色带为红色 .

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

有谁知道这是怎么做的?

谢谢你的帮助 .

3 回答

  • 6

    不需要手动创建另一列的选项是在 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")
    

    filled conditional on level > level2

    或者,如果您只想基于该条件填写为真,

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

    filled conditional on level > level2, not otherwise

    我认为缺少内插填充似乎与 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))
    

    @beetroot's answer

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

  • 13

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

    所以先找到这一行......

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

    enter image description here

  • 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
    

    Fill is interpolated now

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

相关问题