Search code examples
rggplot2boxploterrorbar

Add standard error as shaded area instead of errorbars in geom_boxplot


I have my boxplot and I added the mean with stat_summary as a line over the box plot. I want to add the standard error, but I don't want errorbar.

Basically, I want to add the standard error as shaded area, as you can do using geom_ribbon.

I used the PlantGrowth dataset to show you briefly what I've tried.

library(ggplot2) 

ggplot(PlantGrowth, aes(group, weight))+ 
stat_boxplot( geom='errorbar', linetype=1, width=0.5)+ 
geom_boxplot(fill="yellow4",colour="black",outlier.shape=NA) + 
stat_summary(fun.y=mean, colour="black", geom="line", shape=18, size=1,aes(group=1))+ 
stat_summary(fun.data = mean_se, geom = "errorbar")

I did it using geom_errorbar in stat_summary, and tried to substitute geom_errorbar with geom_ribbon, as I saw in some other examples around the web, but it doesn't work.

Something like this one, but with the error as shaded area instead of error bars (which make it a bit confusing to see)

enter image description here


Solution

  • Layering so many geoms becomes hard to read, but here's a simplified version with a few options. Aside from just paring things down a bit to see what I was editing, I added a tile as a summary geom; tile is similar to rect, except it assumes it will be centered at whatever its x value is, so you don't need to worry about the x-axis placement that geom_rect requires. You might experiment with fill colors and opacity—I made the boxplots white just to illustrate better.

    library(ggplot2) 
    
    gg <- ggplot(PlantGrowth, aes(x = group, y = weight)) +
      stat_boxplot(geom = "errorbar", width = 0.5) +
      geom_boxplot(fill = "white", outlier.shape = NA, width = 0.7) +
      stat_summary(aes(group = 1), fun.y = mean, geom = "line")
    
    gg +
      stat_summary(fun.data = mean_se, geom = "tile", width = 0.7,
                   fill = "pink", alpha = 0.6)
    

    Based on your comments that you want a ribbon, you could instead use a ribbon with group = 1 the same as for the line.

    gg +
      stat_summary(aes(group = 1), fun.data = mean_se, geom = "ribbon", 
                   fill = "pink", alpha = 0.6)
    

    The ribbon doesn't make a lot of sense across a discrete variable, but here's an example with some dummy data for a continuous group, where this setup becomes more reasonable (though IMO still hard to read).

    pg2 <- PlantGrowth
    set.seed(123)
    pg2$cont_group <- floor(runif(nrow(pg2), 1, 6))
    
    ggplot(pg2, aes(x = cont_group, y = weight, group = cont_group)) +
      stat_boxplot(geom = "errorbar", width = 0.5) +
      geom_boxplot(fill = "white", outlier.shape = NA, width = 0.7) +
      stat_summary(aes(group = 1), fun.y = mean, geom = "line") +
      stat_summary(aes(group = 1), fun.data = mean_se, geom = "ribbon", 
                   fill = "pink", alpha = 0.6)