2

I want to add the number of observations below each boxplot (as in the figure- no need for the red square). :) However, I don't know how to annotate this type of boxplot (see figure below).multiple boxplot annotate number of observations

Does anyone know how to do it?

This is the code that I used to plot this figure.

ggplot(data=MIOT1, aes(stage, time, fill=resp)) +
geom_boxplot(color= "black", lwd=0.3) +
stat_summary(fun.y=mean, geom="point", shape=0, size=1, colour="black", position=position_dodge(width=0.75)) +
scale_fill_manual(values=c("grey25", "grey50", "grey67")) +
annotation_custom(mygrobA) +
scale_y_continuous(limits=c(-10,124)) +
theme(panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    strip.background = element_rect(colour="black"),
    panel.border = element_rect(colour = "black", fill="transparent")) +
xlab(bquote(' ')) +
ylab(bquote('Minimum Consecutive Time (s)')) +
labs(title="SATIATION\n") +
theme(axis.title.y = element_text(colour="black",size=10,face="bold"),
    axis.text.x = element_text(colour="black",size=8, face="plain"),
    axis.text.y = element_text(colour="black",size=8, face="plain"),  
    axis.title.x = element_text(colour="black",size=10,face="bold")) +  
theme(panel.background = element_rect(fill = "white")) +
theme(plot.title = element_text(lineheight=.8, size=10, face="bold")) +
theme(legend.title=element_blank(), legend.key = element_rect(fill = NA, colour = NA)) +
theme(legend.position="none") +
theme(legend.background = element_rect(fill=NA)) +
theme(plot.margin = unit(c(.25,.25,.0,.0), "cm"))<i>

EXAMPLE DATA MIOT1 is a numeric variable (y-axis), and I am considering two grouping factors (development stage- x axis) and the response (unresponsive, coastal, lagoon).

Something like

stage  resp  time
pre       U      100
pre       U      80
pre       U       50
pre       C       20
flex       U      80
flex       U       90
flex       C       10
flex        C      20
post      U        40
post      U        30
post      U        60
post       C      80
post      C       100
post       L       50
post       L       40

Thank you! Pedro

Pedro Miguel
  • 39
  • 1
  • 5
  • 1
    Please provide us some sample data that we can work with. Right now we have no idea what `MIOT1` is which makes it hard for us to replicate your problem. A `dput(MIOT1)` would be helpful. For more information check out: http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Mike H. May 19 '16 at 17:23
  • I now added an example data in the question. Thank you! – Pedro Miguel May 19 '16 at 17:39

2 Answers2

4

Here's a simple example of how to do it, using the built-in mtcars data frame:

ggplot(mtcars, aes(factor(cyl), mpg)) + 
  geom_boxplot() +
  geom_text(stat="count", aes(label=..count..), y=min(mtcars$mpg)- 0.6)

In your case, it will be something like

ggplot(data=MIOT1, aes(stage, time, fill=resp)) +
  geom_boxplot(color= "black", lwd=0.3) +
  geom_text(stat="count", aes(label=..count..), y=min(MIOT1$time)) 

where you may have to adjust the y location of the text labels and you might also need to adjust the range of the y-axis to make room for the labels.

UPDATE: I was able to reproduce the error you reported, but I'm not sure how to fix it. Instead, you can pre-summarize the data and then add it to the plot. Here's an example:

library(dplyr)

# Get counts by desired grouping variables
counts = mtcars %>% group_by(cyl, am) %>% tally


ggplot(mtcars, aes(factor(cyl), mpg, fill=factor(am))) + 
  geom_boxplot(position=position_dodge(0.9)) +
  geom_text(data=counts, aes(label=n, y=min(mtcars$mpg) - 0.6),
        position=position_dodge(0.9))
eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Thank you for the reply eipi10. I am almost there. However, the code that you provided allows me to get the counts for each group of the factor "Development Stage" (x-axis). This means that I have 3 counts. However, I want the counts for each boxplot, which is 9 counts. Thank you once again. – Pedro Miguel May 19 '16 at 17:56
  • eipi10... I just noticed that the 9 counts are all there, but they are superimposed in the center in blocks of 3. I tried position.dodge but it doesn't work. Any suggestions? – Pedro Miguel May 19 '16 at 17:58
  • Something like `position=position.dodge(0.5)` (use the same dodge amount as for the boxplots). – eipi10 May 19 '16 at 18:05
  • hum... I added this piece of code and I got an error geom_text(stat="count", aes(label=..count..), y=min(MIOT1$time)- 6, position=position_dodge(width=0.75)) Error in collide(data, params$width, "position_dodge", pos_dodge, check.width = FALSE) : Neither y nor ymax defined I'm sure I'm doing something wrong! :( – Pedro Miguel May 19 '16 at 18:11
  • Your update answered my question and find an alternative solution for the problem posed by the position.dodge error. Thank you eipi10! :) – Pedro Miguel May 19 '16 at 21:38
1

IN SUMMARY EIPI10 ANSWERED MY QUESTION:

library(dplyr)

# Get counts by desired grouping variables
    counts = mtcars %>% group_by(cyl, am) %>% tally


    ggplot(mtcars, aes(factor(cyl), mpg, fill=factor(am))) + 
    geom_boxplot(position=position_dodge(0.9)) +
    geom_text(data=counts, aes(label=n, y=min(mtcars$mpg) - 0.6), position=position_dodge(0.9)
wp78de
  • 18,207
  • 7
  • 43
  • 71
Pedro Miguel
  • 39
  • 1
  • 5