0
votes

I have the following reproducible code that gives me a boxplot with jittered points (nominal x axis with another grouping factor):

ggplot(mtcars,aes(as.factor(cyl),disp))+
 geom_jitter(aes(color=as.factor(am)),position=position_jitterdodge(dodge.width=0.88),cex=.8)+
 geom_boxplot(aes(fill=as.factor(am)),width=1,outlier.shape=NA,position=position_dodge(width=.88))+
 scale_fill_manual(values=c(NA,NA))

Boxplot Example

I would like to add whiskers to the boxplot, but the only way I know how is to use stat_boxplot, which puts an error bar straight through the IQR range of the boxplot, and it looks quite unattractive:

ggplot(mtcars,aes(as.factor(cyl),disp))+
  geom_jitter(aes(color=as.factor(am)),position=position_jitterdodge(dodge.width=0.88),cex=.8)+
  stat_boxplot(geom ='errorbar',position=position_dodge(width=.88),aes(fill=as.factor(am))) + 
  geom_boxplot(aes(fill=as.factor(am)),width=1,outlier.shape=NA,position=position_dodge(width=.88))+
  scale_fill_manual(values=c(NA,NA))

Second example

I have tried to do a work around by writing my own code for the upper and lower whiskers, and then using statsummary to put only the whisker lines I need, like this:

upper_whisker<-function(x) {
  work<-quantile(x,na.rm=T,names=F)
  obs<-max(x[x<=work[4]],na.rm=T)
  whisker<-obs+1.5*IQR(x,na.rm=T)
  return(whisker)
}

lower_whisker<-function(x) {
  work<-quantile(x,na.rm=T,names=F)
  obs<-min(x[x>=work[2]],na.rm=T)
  whisker<-obs-1.5*IQR(x,na.rm=T)
  return(whisker)
}
ggplot(mtcars,aes(as.factor(cyl),disp))+
  geom_jitter(aes(color=as.factor(am)),position=position_jitterdodge(dodge.width=0.88),cex=.8)+
  #stat_boxplot(geom ='errorbar',position=position_dodge(width=.88),aes(fill=as.factor(am))) + 
  stat_summary(aes(group=as.factor(am)),fun.y=upper_whisker,fun.ymin=upper_whisker,fun.ymax=upper_whisker,geom="errorbar",color="black",width=0.5,size=0.4,position=position_dodge(width=0.88))+
  stat_summary(aes(group=as.factor(am)),fun.y=lower_whisker,fun.ymin=lower_whisker,fun.ymax=lower_whisker,geom="errorbar",color="black",width=0.5,size=0.4,position=position_dodge(width=0.88))+
  geom_boxplot(aes(fill=as.factor(am)),width=1,outlier.shape=NA,position=position_dodge(width=.88))+
  scale_fill_manual(values=c(NA,NA))

Final Example

But as you can see the whiskers are not in the right place, so I must be doing something wrong with the formula (I found the formula here: https://www.r-bloggers.com/whisker-of-boxplot/)

If anyone could tell me how to do the formula correctly or if they have any better ideas about how to do whiskers the way I need them, I would much appreciate it.

1

1 Answers

0
votes

In this line: obs<-min(x[x>=work[2]],na.rm=T), you take the minimum value of x, where x is above 1Q (which is just 1Q). This is not what you wanted to do.

Replace your whisker functions by:

EDIT 18/12/09 - use R boxplot to get coordinates

upper_whisker<-function(x) {
  box_stats <- boxplot(x)$stats[5]
  return(box_stats)
}

lower_whisker<-function(x) {
  box_stats <- boxplot(x)$stats[1]
  return(box_stats)
}