Add ribbon showing mean and interquartile range to ggplot2

You can use stat_summary with geom_smooth:

library(ggplot2)
set.seed(47)

df <- data.frame(a = runif(100), 
                 b = runif(100), 
                 c = runif(100), 
                 d = rnorm(2700), 
                 dates = as.Date("2013-12-31") + 1:60)
df$Metric <- ifelse(df$a > 0.5, "a", "b")
df$Methodology <- factor(ifelse(df$a > 0.5, "One", "Two"))


ggplot(df, aes(x = dates, y = b)) +
    geom_point() +
    stat_smooth(size = 1.5) +
    geom_smooth(stat = 'summary', alpha = 0.2, fill = 'red', color = 'red',
                fun.data = median_hilow, fun.args = list(conf.int = 1)) + 
    scale_x_date(date_breaks = "1 week", date_labels =  "%d-%b-%y") +
    facet_wrap(~ Methodology + Metric, ncol = 1)
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Since conf.int = 1, this plots a ribbon between the minimum and maximum at each x value, with the median as the line. If you actually want to plot 25th and 75th percentiles, set conf.int = 0.5. On this data, there aren't enough observations at each x value for that to look very different, though, so on some new sample data,

library(ggplot2)
set.seed(47)

ggplot(tibble::tibble(x = rep(seq(0, 4*pi, length.out = 50), 50), 
                      y = rnorm(2500) * sin(x) + sin(x)), 
       aes(x, y)) + 
    geom_point(alpha = 0.1) + 
    geom_smooth(fill = 'darkblue') + 
    geom_smooth(stat = 'summary', color = 'red', fill = 'red', alpha = 0.2, 
                fun.data = median_hilow, fun.args = list(conf.int = 0.5))
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

median_hilow (really Hmisc::smedian.hilow) doesn't allow you to set the type of quantile, though, so for more precise control, rewrite the function (returning a similarly structured data frame) or pass separate functions for each statistic to the fun.y, fun.ymin and fun.ymax parameters.

Tags:

R

Ggplot2