【问题标题】:How to color/shade the area between two lines in ggplot2?如何在ggplot2中对两条线之间的区域进行着色/着色?
【发布时间】:2021-08-13 10:04:57
【问题描述】:

我想用两条线绘制一个图,分别代表观测数据和来自特殊模型的数据。还有另外两条线表示其他模型的可变性的最大值和最小值。目标是将这两条线之间的区域涂成灰色,以便前两条线仍然可见。

这里是重现数据的代码:

# create the data set
Month.vec <- c(1:12)
Model.vec <- c(70.33056, 58.91058, 73.40891, 74.42824, 108.45975, 125.85887, 126.02867, 102.54128, 70.66263, 61.30316, 66.04057, 75.75262)
Obs.vec <- c(62.64178, 52.39356, 63.07376, 52.87248, 70.80587, 81.85081, 88.29134, 77.22920, 67.67458, 64.74425, 63.96322, 69.89868)
Up_lim.vec <- c(83.46967, 71.27700,  86.43001,  77.62739, 108.32674, 112.61118, 125.43512,  93.71193,  80.17298,  75.01851,  79.05700,  85.40042)
Low_lim.vec <- c(76.44381, 65.19571, 74.27778, 59.91012, 82.14684, 84.09151, 77.91529, 66.21702, 60.89712, 67.85613, 72.49409, 79.13741)
df <- as.data.frame(cbind(Month.vec, Obs.vec, Model.vec, Up_lim.vec, Low_lim.vec))
colnames(df) <- c("Month", "Observation", "Model", "Upper Limit", "Lower Limit")

四线的“正常”图很容易完成:

# plot 
df %>% 
  as_tibble() %>% 
  pivot_longer(-1) %>% 
  ggplot(aes(Month, value, color = name)) + 
  scale_color_manual("",values= c("blue", "yellow", "red", "black")) +
  scale_x_continuous(breaks = seq(1, 12, by = 1)) +
  scale_y_continuous(breaks = seq(0, 140, by = 20)) +
  ylab("Precipitation [mm]") +
  geom_line() +
  theme_bw()

这会导致以下输出:

所以想法是黑线和蓝线之间的区域用灰色或类似的颜色着色,这样蓝线和黄线仍然可见。

this 问题的结果应该看起来像这样:

我知道这里有一些类似的问题,其中大多数暗示使用geom_ribbon。 我试过了,但只收到以下错误消息:

Error: Aesthetics must be either length 1 or the same as the data (48): ymax and ymin

有人知道怎么做吗?

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    我认为将数据保存为更宽的格式然后使用geom_ribbon 创建阴影区域会更容易:

    df %>% 
      as_tibble() %>% 
      ggplot +
      geom_line(aes(Month, Model, color = 'Model')) +
      geom_line(aes(Month, Observation, color = 'Observation')) +
      geom_ribbon(aes(Month, ymax=`Upper Limit`, ymin=`Lower Limit`), fill="grey", alpha=0.25) +
      scale_x_continuous(breaks = seq(1, 12, by = 1)) +
      scale_y_continuous(breaks = seq(0, 140, by = 20)) +
      scale_color_manual(values = c('Model' = 'yellow','Observation' = 'red')) +
      ylab("Precipitation [mm]") +
      theme_bw() +
      theme(legend.title = element_blank())
    

    【讨论】:

    • 非常感谢。这里提出的所有解决方案都有效。这一款确实似乎是最优雅的一款。
    【解决方案2】:

    如果您想保留 Upper LimitLower Limit 行,您可以为功能区创建一个数据框(尽管不可否认,它的解决方案不如上面的优雅):

    library(stringr)
    
    df <- df %>% 
      as_tibble() %>% 
      pivot_longer(-1)
    
    ribbon_df <- df %>% filter(str_detect(name, "Limit")) %>%
        pivot_wider(names_from = name, values_from = value) %>%
        mutate(value = `Upper Limit` ) %>%
        mutate(name = "Upper Limit")
    
    df %>% ggplot(aes(Month, value, color = name)) + 
        scale_color_manual("",values= c("blue", "yellow", "red", "black")) +
        scale_x_continuous(breaks = seq(1, 12, by = 1)) +
        scale_y_continuous(breaks = seq(0, 140, by = 20)) +
        ylab("Precipitation [mm]") +
        geom_ribbon(data = ribbon_df, aes(ymin = `Lower Limit`, ymax = `Upper Limit`), fill = "grey") + 
        geom_line() +
        theme_bw()
    

    【讨论】:

      【解决方案3】:

      如果您使用较长的格式,则需要一个宽表来存储 geom_ribbon 数据。

      library(tidyverse)
      # create the data set
      Month.vec <- c(1:12)
      Model.vec <- c(70.33056, 58.91058, 73.40891, 74.42824, 108.45975, 125.85887, 126.02867, 102.54128, 70.66263, 61.30316, 66.04057, 75.75262)
      Obs.vec <- c(62.64178, 52.39356, 63.07376, 52.87248, 70.80587, 81.85081, 88.29134, 77.22920, 67.67458, 64.74425, 63.96322, 69.89868)
      Up_lim.vec <- c(83.46967, 71.27700,  86.43001,  77.62739, 108.32674, 112.61118, 125.43512,  93.71193,  80.17298,  75.01851,  79.05700,  85.40042)
      Low_lim.vec <- c(76.44381, 65.19571, 74.27778, 59.91012, 82.14684, 84.09151, 77.91529, 66.21702, 60.89712, 67.85613, 72.49409, 79.13741)
      df <- as.data.frame(cbind(Month.vec, Obs.vec, Model.vec, Up_lim.vec, Low_lim.vec))
      colnames(df) <- c("Month", "Observation", "Model", "UL", "LL")
      
      df_new <- df %>% 
        as_tibble() %>% 
        pivot_longer(-1)
      
      
      
        ggplot() + 
       # scale_color_manual("",values= c("blue", "yellow", "red", "black")) +
        scale_x_continuous(breaks = seq(1, 12, by = 1)) +
        scale_y_continuous(breaks = seq(0, 140, by = 20)) +
        ylab("Precipitation [mm]") +
        geom_line(data=df_new,aes(Month, value, color = name)) +
        geom_ribbon(data=df, aes(x=Month,ymin = LL, ymax = UL),alpha=0.5)
        theme_bw()
      

      这会导致这个

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-13
        • 2012-09-07
        • 1970-01-01
        • 2021-06-07
        • 2011-04-10
        • 2017-07-13
        • 1970-01-01
        相关资源
        最近更新 更多