I've created a side-by-side boxplot using ggplot2.
p <- ggplot(mtcars, aes(x=factor(cyl), y=mpg))
p + geom_boxplot(aes(fill=factor(cyl)))
I want to annotate with min, max, 1st quartile, median and 3rd quartile in the plot. I know geom_text()
can do so and may be fivenum()
is useful. But I cannot figure out how exactly I can do!. These values should be displayed in my plot.
The most succinct way I can think of is to use stat_summary
. I've also mapped the labels to a color aesthetic, but you can, of course, set the labels to a single color if you wish:
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", ..y..), color=factor(cyl)),
position=position_nudge(x=0.33), size=3.5) +
theme_bw()
In the code above we use quantile
as the summary function to get the label values. ..y..
refers back to the output of the quantile
function (in general, ..*..
is a ggplot construction for using values calculated within ggplot).
One way is to simply make the data.frame you need, and pass it to geom_text
or geom_label
:
library(dplyr)
cyl_fivenum <- mtcars %>%
group_by(cyl) %>%
summarise(five = list(fivenum(mpg))) %>%
tidyr::unnest()
ggplot(mtcars, aes(x=factor(cyl), y=mpg)) +
geom_boxplot(aes(fill=factor(cyl))) +
geom_text(data = cyl_fivenum,
aes(x = factor(cyl), y = five, label = five),
nudge_x = .5)
In case anyone is dealing with large ranges and has to log10 transform their y-axis, I found some code that works great. Just add 10^..y..
and scale_y_log10()
. If you don't add 10^
before ..y..
the actual quantile values will be log transformed and displayed as such.
Does not work
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", ..y..), color=factor(cyl)),
position=position_nudge(x=0.45), size=3.5) +
scale_y_log10()+
theme_bw()
Works great
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", 10^..y..), color=factor(cyl)),
position=position_nudge(x=0.45), size=3.5) +
scale_y_log10()+
theme_bw()