Search code examples
rboxplotfilloutliers

Fill outliers with same color as Boxplots Fill color in ggplot R?


I want outliers to appear in the same color as the boxplot fill color(not the outline). I have tried different ways and none of them work. Any help would be really appreciated.

ToothGrowth$dose <- as.factor(ToothGrowth$dose)
p <- ggplot(ToothGrowth, aes(x=dose, y=len))+
     geom_boxplot(width=0.3,aes(fill=dose),outlier.colour = NA)+
     geom_point()+
     scale_fill_manual(values=c("firebrick", "royalblue","yellow"))
p

boxplots for different doses


Solution

  • We can set the outlier.shape to "21" so that it will inherit the fill colors and plot the points before the boxplot:

    ToothGrowth$dose <- as.factor(ToothGrowth$dose)
    ggplot(ToothGrowth, aes(x=dose, y=len))+
      geom_point()+
      geom_boxplot(width=0.3,aes(fill=dose),outlier.shape = 21)+
      scale_fill_manual(values=c("firebrick", "royalblue","yellow"))
    

    enter image description here It's hardly visible in the picture but the outlier at dose 0.5 is red.


    Edit To also display points inside the box:

    is_outlier <- function(x) {
      return(x < quantile(x, 0.25) - 1.5 * IQR(x) | x > quantile(x, 0.75) + 1.5 * IQR(x))
    }
    
    ToothGrowth %>% 
      group_by(dose) %>% 
      mutate(outlier = ifelse(is_outlier(len), as.numeric(NA), as.numeric(len))) %>% 
    ggplot(aes(x=dose, y=len))+
      geom_boxplot(width=0.3,aes(fill=dose),outlier.shape = 21)+
      geom_point(aes(x = dose, y = outlier))+
      scale_fill_manual(values=c("firebrick", "royalblue","yellow"))