rggplot2geom-ribbon

ggplot2 geom_ribbon not plotting


For some reason I can't figure out my geom_ribbon are not working

Data:

structure(list(row = c("1", "2", "3", "4", "5", "6", "7", "8", 
"9", "10", "11", "12", "13", "14", "15"), month = c("12", "01", 
"02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", 
"01", "02"), cumtmean = c(9.4, 7.8, 7.8, 12.6, 14.9, 15.9, 23.5, 
25.7, 26.5, 20.7, 19.2, 16.6, NA, NA, NA), cump00tmean = c(2.5, 
3.1, 3.9, 6.1, 8.7, 10.6, 17.4, 19.2, 19.9, 16.6, 14.6, 12.4, 
2.5, 3.1, 3.9), cump20tmean = c(4.8, 5.1, 5.5, 9.1, 10.5, 12.1, 
19.4, 21.7, 22.4, 18.8, 16.4, 13.8, 4.8, 5.1, 5.5), cump40tmean = c(6.1, 
5.8, 6.2, 9.8, 11.1, 12.8, 20.7, 22.6, 22.9, 19.9, 17.1, 14.5, 
6.1, 5.8, 6.2), cump50tmean = c(6.4, 6, 6.4, 10.1, 11.4, 13.1, 
21.2, 22.9, 23.2, 20.4, 17.4, 14.8, 6.4, 6, 6.4), cump60tmean = c(6.8, 
6.4, 6.7, 10.5, 11.8, 13.3, 22, 23.2, 23.5, 20.9, 17.9, 15.1, 
6.8, 6.4, 6.7), cump80tmean = c(7.4, 7.1, 7.4, 11.7, 12.4, 14.2, 
22.8, 24.2, 24.8, 21.8, 18.5, 15.7, 7.4, 7.1, 7.4), cump100tmean = c(9.8, 
9.1, 9.8, 14.7, 15.3, 16.1, 26.4, 27.2, 27.4, 24.2, 20.6, 17.4, 
9.8, 9.1, 9.8)), class = "data.frame", row.names = c(NA, -15L
))

Code:

  p <- ggplot2::ggplot(data = plot_data, aes(x = row)) +
    #ggplot2::geom_point(aes(y = cumtmean), color = "red", na.rm = TRUE) +
    ggplot2::geom_line(aes(y = cumtmean, group = 1, color = "cumtmean"), na.rm = TRUE) +
    ggplot2::scale_color_manual(
      values = c("cumtmean" = "black"), 
      label = paste0("Cumulative seasonal mean temp. (", selected_year, ")"), guide = guide_legend(order = 1)) +
    ggplot2::geom_ribbon(
      aes(ymin = cump100tmean, ymax = cump100tmean + 4, fill = ">P100"), alpha = 0.3, 
      color = "#b2182b", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump80tmean, ymax = cump100tmean, fill = "P100"), alpha = 0.3, 
      color = "#ef8a62", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump60tmean, ymax = cump80tmean, fill = "P80"), alpha = 0.3, 
      color = "#fddbc7", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump40tmean, ymax = cump60tmean, fill = "P60"), alpha = 0.3, 
      color = NA, linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump20tmean, ymax = cump40tmean, fill = "P40"), alpha = 0.3, 
      color = "#d1e5f0", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump00tmean, ymax = cump20tmean, fill = "P20"), alpha = 0.3, 
      color = "#67a9cf", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::geom_ribbon(
      aes(ymin = cump00tmean - 4, ymax = cump00tmean, fill = "P00"), alpha = 0.3, 
      color = "#2166ac", linetype = "51", lineend = "round", linejoin = "round") +
    ggplot2::scale_fill_manual(
      values = c(">P100" = "#b2182b", "P100" = "#ef8a62", "P80" = "#fddbc7", "P60" = "#f7f7f7",
                 "P40" = "#d1e5f0", "P20" = "#67a9cf", "P00" = "#2166ac"),
      breaks = c(">P100", "P100", "P80", "P60", "P40", "P20", "P00"), # To give order
      labels = c(">P100" = expr(paste("Extrem. hot season (>", italic(P[100]), ") (", 
                                     !!ref_start_year, "-", !!ref_end_year, ")")), 
                 "P100" = expr(paste("Very hot season (", italic(P[80]), "-", italic(P[95]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")), 
                 "P80" = expr(paste("Hot season (", italic(P[60]), "-", italic(P[80]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")), 
                 "P60" = expr(paste("Normal season (", italic(P[40]), "-", italic(P[60]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")),
                 "P40" = expr(paste("Cold season (", italic(P[20]), "-", italic(P[40]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")),
                 "P20" = expr(paste("Very cold season (", italic(P[05]), "-", italic(P[20]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")),
                 "P00" = expr(paste("Extrem. cold season (<", italic(P[00]), ") (", 
                                    !!ref_start_year, "-", !!ref_end_year, ")")))) +
    ggplot2::scale_x_discrete(
      limits = plot_data$row,
      labels = c(
        paste0("Dec", (as.numeric(2023) - 1) %% 100), "Jan", "Feb", "Mar", "Apr", "May", 
        "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 
        paste0("Jan", (as.numeric(2023) + 1) %% 100),
        paste0("Feb", (as.numeric(2023) + 1) %% 100)
      )) +
    ggplot2::scale_y_continuous(
      limits = c(min(min(plot_data$cumtmean, na.rm = TRUE), min(plot_data$cump00tmean, na.rm = TRUE) - 4) - 4, 
                 max(max(plot_data$cumtmean, na.rm = TRUE), max(plot_data$cump100tmean, na.rm = TRUE) + 4) + 2),
      breaks = seq(from = round(min(min(plot_data$cumtmean, na.rm = TRUE), min(plot_data$cump00tmean, na.rm = TRUE) - 4) - 4), 
                   to = round(max(max(plot_data$cumtmean, na.rm = TRUE), max(plot_data$cump100tmean, na.rm = TRUE) + 4) + 3), by = 5),
      labels = function(x) paste0(x, "ºC")) +
    ggthemes::theme_hc(base_size = 15) +
    ggplot2::theme(
      plot.title = ggplot2::element_text(hjust = 1, face = "bold", family = "sans", size = 35),
      plot.subtitle = ggplot2::element_text(hjust = 1, size = 25),
      legend.background = ggplot2::element_blank(),
      legend.box.background = ggplot2::element_rect(fill = "white", color = "black", linewidth = 0.75),
      legend.position = c(0.15, 0.85),
      legend.spacing = ggplot2::unit(0, "cm"),
      legend.margin = ggplot2::margin(r = 5, l = 5, b = 5),
      legend.title = element_blank()
    )

Solution

  • The problem is that your x axis is discrete, so every layer needs a group = 1 to span the x axis. It would make much more sense to convert your x axis to actual dates, and pivot into long format so you don't need multiple ribbon layers:

    library(tidyverse)
    library(ggthemes)
    
    plot_data %>%
      mutate(Date = seq(as.Date("2022-12-01"), by = "month", len = n())) %>%
      pivot_longer(starts_with("cump")) %>%
      mutate(low = value, high = lead(value), .by = row) %>%
      filter(complete.cases(.)) %>%
      mutate(mean = cumtmean) %>%
      mutate(name = gsub("cump|tmean", "", name)) %>%
      mutate(name = paste(as.numeric(name), as.numeric(name) + 20, sep = " - ")) %>%
      mutate(range = paste("P", name)) %>%
      ggplot(aes(Date, mean)) +
      geom_ribbon(aes(fill = range, ymin = low, ymax = high), alpha = 0.4) +
      geom_line(stat = "summary", fun = mean, aes(linetype = "cumtmean"),
                linewidth = 1) +
      scale_linetype_manual(NULL, values = 1) +
      scale_fill_manual(NULL, guide = guide_legend(reverse = TRUE),
                        values = c("#2166ac", "#67a9cf", "#d1e5f0",
                                   "#fddbc7", "#ef8a62", "#b2182b" )) +
      theme_hc(base_size = 15) +
      theme(plot.title = element_text(hjust = 1, face = "bold", 
                                      family = "sans", size = 35),
            plot.subtitle = element_text(hjust = 1, size = 25),
            legend.background = element_blank(),
            legend.box.background = element_rect(fill = "white", color = "black", 
                                                 linewidth = 0.75),
            legend.position = c(0.15, 0.85),
            legend.spacing = unit(0, "cm"),
            legend.margin = margin(r = 5, l = 5, b = 5),
            legend.title = element_blank())
    

    enter image description here