How to modify whiskers of a boxplot in ggplot2?

2020-07-10 11:01发布

问题:

I'll start with an MWE:

library(ggplot2)

p <- ggplot(mtcars, aes(factor(cyl), mpg, fill = factor(am)))
p + geom_boxplot()

I'd like to modify the colour of the whiskers, e.g., set it to red. I don't think it's possible to do this directly both geom_boxplot, so this is my workaround:

library(Hmisc)

stat_sum_df <- function(fun, geom = "crossbar", ...) {
  stat_summary(fun.data = fun, geom = geom, width = 0.4, ...)
}

p + stat_boxplot(geom = 'linerange', colour = "red", position = "dodge) +
    stat_sum_df("median_hilow", conf.int = 0.5, position = "dodge") 

The line ranges are stacked on top of each other. So next try:

p + stat_boxplot(geom = 'linerange', colour = "red", position = position_dodge(width = .5)) +
   stat_sum_df("median_hilow",conf.int=0.5, position = position_dodge(width = .5))

Looks nicer, but now there is a fixed space between the boxes (compare cyl = 8 on first and third plot). As I'm going to use this code for different number of levels of am (of course in my real data, it's not am), I don't know in advance how wide the boxes themselves will be, so I can't set a fixed width for the linerange without specifying a fixed width for the boxes.

Is there a way either to selectively modify whiskers of a boxplot or to adjust space between linerange elements according to space between the boxes?

回答1:

How about plotting two boxplots on top of each other. One with red lines and a second one on top without any wiskers at all.

p + geom_boxplot(color="red") + geom_boxplot(aes(ymin=..lower.., ymax=..upper..)) 


回答2:

Another option is to plot error bars and on top of them the boxplots without the whiskers:

library(ggplot2)
p + stat_boxplot(geom = "errorbar", colour = "red") + 
  geom_boxplot(coef = 0, outlier.size = 0)