Search code examples
rdataframeggplot2dplyr

ggplot how to plot ribbons in R from dataframe


I have dataframe which has Category avg_fc,avg_la,sd_fc,sd_la values in column Category.

df = data.frame (Date=c("2020-01-10","2020-01-10","2020-01-10","2020-01-10" 
                        ,"2020-01-11","2020-01-11","2020-01-11","2020-01-11",
                        "2020-01-12","2020-01-12","2020-01-12","2020-01-12" 
                        ,"2020-01-13","2020-01-13","2020-01-13","2020-01-13"), 
                 Category=c("avg_fc","avg_la","sd_fc","sd_la","avg_fc","avg_la","sd_fc","sd_la","avg_fc",
                            "avg_la","sd_fc","sd_la","avg_fc","avg_la","sd_fc","sd_la"), 
                 Value=c(25.5,40.5, 8.1,4.3, 29.5 ,31.5,5.6,9.1,  20.5,43.5, 4.1,8.3, 35.5 ,38.5,2.6,3.1))

From the given dataframe I would like to generate a ggplot where Category avg_fc and avg_la are the geom_line and Category sd_fc and sd_la become the shaded area. As shown in the example of ggplot_ribbons plot below.

Is it possible to achieve that from the given dataframe ? Below function attempts to draw line charts where i would like to see sd_fc and sd_la as shaded area.

generate_chart <- function(data, x, y, colors,Category,title) {
  
  data %>%
    group_by({{ x }})  %>%
    ggplot() +
    geom_line(aes(x = {{x}}, y = {{y}}, group=1, color = {{Category}})) +
    theme_light() +
    ggtitle(title)
  
}

plt_mm <- generate_chart(
  data = df,
  x = Date,
  y= Value,
  title = "Money Chart",
  colors=Category,
  Category = Category
)

enter image description here

enter image description here


Solution

  • I don't see any option to achieve your desired result without reshaping your data so that the avg and sd values are in separate columns:

    library(tidyr)
    library(ggplot2)
    
    df |>
      pivot_wider(names_from = Category, values_from = Value) |>
      pivot_longer(-Date, names_to = c(".value", "category"), names_sep = "_") |>
      ggplot(aes(x = Date, group = category)) +
      geom_line(aes(y = avg, color = category)) +
      geom_ribbon(
        aes(ymin = avg - sd, ymax = avg + sd, fill = category),
        alpha = .3
      ) +
      theme_light() +
      ggtitle("Money Chart")