Search code examples
ggplot2boxplotgeom

geom_boxplot custom color for quantiles


I have a simple ggplot boxplot like in this example

library(ggplot2)

dat <- ToothGrowth

ToothGrowth$dose <- as.factor(ToothGrowth$dose)

p <- ggplot(ToothGrowth, aes(x=dose, y=len)) + 
  geom_boxplot() +
  facet_grid(~supp)
p

Goal:

I want the boxes of the quantiles in different colors, as seen in the image below.

One Hint could be this link: https://ggplot2.tidyverse.org/reference/geom_segment.html.

But I'm not shure how to implement this for the ractangles. In addition I have in my plots a facid_grid, and there the coloration should work as well. Here can you see what I want to achieve in the end.

This is what it should look like

Do you have any suggestions?


Solution

  • You could do like this: First, calculate the median, first and third quartile (quart1 and quart3) for ToothGrowth, grouped by supp and dose. Afterwards you can fill in the lower and upper rectangles of the boxplots. Since you wanted four different colors, I added four different rectangles.

    ToothGrowth <- ToothGrowth %>% mutate(dose = factor(dose)) %>% group_by(supp, dose) %>% 
      mutate(median = median(len), quart1 = quantile(len, 0.25), quart3 = quantile(len, 0.75))
    
    ggplot(ToothGrowth, aes(dose, len)) + 
      geom_boxplot(width = 0.6) +
      facet_grid(~supp) +
      geom_rect(data = subset(ToothGrowth, supp == "OJ"), 
                aes(xmin = as.numeric(dose) - 0.3, xmax = as.numeric(dose) + 0.3, ymin = quart1, ymax = median), 
                fill = "#008AA7", color = "black") +
      geom_rect(data = subset(ToothGrowth, supp == "VC"), 
                aes(xmin = as.numeric(dose) - 0.3, xmax = as.numeric(dose) + 0.3, ymin = quart1, ymax = median), 
                fill = "#005645", color = "black") +
      geom_rect(data = subset(ToothGrowth, supp == "OJ"), 
                aes(xmin = as.numeric(dose) - 0.3, xmax = as.numeric(dose) + 0.3, ymin = median, ymax = quart3), 
                fill = "#A2EFFD", color = "black") +
      geom_rect(data = subset(ToothGrowth, supp == "VC"), 
                aes(xmin = as.numeric(dose) - 0.3, xmax = as.numeric(dose) + 0.3, ymin = median, ymax = quart3), 
                fill = "#90AC9E", color = "black")
    

    Which gives the following plot:

    enter image description here