Put whisker ends on boxplot
Asked Answered
S

4

58

I would like to put perpendicular lines at the ends of the whiskers like the boxplot function automatically gives.

Stanfield answered 20/10, 2012 at 23:18 Comment(6)
you can do this by calculating the quantile where ggplot draws the lines and drawing your own geom_segment or geom_crossbar. see this questionAricaarick
Is there some reason why this must be done in ggplot2, and not using boxplot which already does what you want, or is this question of purely academic interest...?Dawson
@Aricaarick Thanks, I've checked out that question but it's too advanced for me and I keep getting errors, I don't know which bits to replace with what, sorry :/Stanfield
@Jake It's purely aesthetic! I have an assignment requiring 2 graphs, one boxplot, one interaction graph. I've created the interaction graph in ggplot2, and would like the boxplot to be consistent (with the axes labels close up to the tick mark labels)....Stanfield
@Jake @ Justin Alternatively, is there a way I can move the position of the axes labels in base boxplot so that they are closer to the tick mark labels and in bold? I'm sure I'm being too pernickety, but I would like the graphs to be consistent.Stanfield
@Jake @ Justin Maybe I wouldn't lose marks for the ggplot2 boxplot not having ends on the whiskers but I just think with the ends on the whiskers is a more traditional boxplot, and it's easier to figure out what the amounts are with the ends on them. Thanks for responding :)Stanfield
T
73

As hinted but not implemented by @Roland, you can use stat_boxplot to implement this. The trick calling _boxplot twice and is to set the geom to errorbar for one of the calls.

Note that as R uses a pen and paper approach it is advisable to implement the error bars first the draw the traditional boxplot over the top.

Using @Roland's dummy data df

ggplot(df, aes(x=cond, y = value))  + 
 stat_boxplot(geom ='errorbar') + 
 geom_boxplot() # shorthand for  stat_boxplot(geom='boxplot')

enter image description here

The help for stat_boxplot (?stat_boxplot) detail the various values computed and saved in a data.frame

Tbilisi answered 21/10, 2012 at 22:58 Comment(3)
how can I resize these whisker-lines if I use geom_boxplot(width=.2) ?Malo
@ Produnis To resize the whiskers lines add the argument stat_params = list(width = 0.5) inside the function: stat_boxplot. See the result in my answer.Stirps
@Malo and others. Currently: geom_boxplot(width = 0.2) + stat_boxplot(geom = "errorbar", width = 0.2), where the values selected in the boxplot and in the error bars must match. For whiskers that span half the box, you would set width = 0.2 and width = 0.1.Arteriotomy
S
39

To resize the whiskers lines we can use the argument width = 0.5 inside the function: stat_boxplot

set.seed(42)
df <- data.frame(cond = factor(rep(c("A", "B"), each = 500)), 
                 value = c(rnorm(500, mean = 1, sd = 0.2), 
                           rnorm(500, mean = 1.5, sd = 0.1))) 

library(ggplot2)
ggplot(df, aes(x = cond, y = value)) +
       stat_boxplot(geom = "errorbar", width = 0.5) +  
       geom_boxplot() 

enter image description here

Stirps answered 7/7, 2015 at 12:22 Comment(7)
This doesn't seem to work for me; I get Error: Unknown parameters: stat_params. What version of R are you using?Commingle
@Commingle I modified the answer. The new version ggplo2 2.0.0 doesn't accept that argument stat_params . Now it should work.Stirps
One thing to note though is that this solution puts the error bars on top of the box, which is a bit odd; is there a way of having the vertical bar not run on top of the box?Commingle
Awesome! Obvious now that I think about it. Thanks!Commingle
I tried using this nice code in combination with a "fill" statement for subgroup coloring. It works without setting width, but with the width setting it unfortunately leads to weird effects.Ashurbanipal
In order to avoid the error bars on top of the box I did stat_boxplot(geom = 'errorbar') + geom_boxplot(inherit.aes = TRUE)Ellingson
@Facottons I do not get your point. The default argument for inherit.aes is TRUE, so geom_boxplot(inherit.aes = TRUE) and geom_boxplot() are identical.Stirps
C
8

It might be possible to use stat_boxplot to calculate the whisker ends, but I am not enough of a ggplot2 wizard, so I use the base function for that.

set.seed(42)
df <- data.frame(cond = factor( rep(c("A","B"), each=500) ), 
                 value = c(rnorm(500,mean=1,sd=0.2),rnorm(500, mean=1.5,sd=0.1)))


whisk <- function(df,cond_col=1,val_col=2) {
  require(reshape2)
  condname <- names(df)[cond_col]
  names(df)[cond_col] <- "cond" 
  names(df)[val_col] <- "value"
  b <- boxplot(value~cond,data=df,plot=FALSE)
  df2 <- cbind(as.data.frame(b$stats),c("min","lq","m","uq","max"))
  names(df2) <- c(levels(df$cond),"pos")
  df2 <- melt(df2,id="pos",variable.name="cond")
  df2 <- dcast(df2,cond~pos)  
  names(df2)[1] <- condname
  df2
}



library(ggplot2)

plot1 <- ggplot(df, aes(x=cond)) 
plot1 <- plot1 + geom_errorbar(aes(ymin=min,ymax=max),data=whisk(df),width = 0.5)
plot1 <- plot1 + geom_boxplot(aes(y=value))
plot1

boxplot with horizontal at whisker ends

Charnel answered 21/10, 2012 at 9:13 Comment(0)
M
2

In the latest version of ggplot2 v3.5.0 we can now use the staplewidth argument in geom_boxplot to add some whiskers to the ends. According to the documentation:

The relative width of staples to the width of the box. Staples mark the ends of the whiskers with a line.

So with staplewidth of 0 we don't have whiskers. Here is some reproducible example:

# Install latest version
# install.packages("ggplot2")
library(ggplot2)
ggplot(iris, aes(x=Species, y = Sepal.Length))  + 
  geom_boxplot(staplewidth = 1)

Created on 2024-02-27 with reprex v2.0.2

Meant answered 27/2 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.