1

Following this question: Add number of observations per group in ggplot2 boxplot, how do I change the colours of stat_summary?

Below is the example code:

give.n <- function(x){
      return(c(y = median(x)*1.05, label = length(x))) 
    }    


p <- ggplot(mtcars, aes(factor(vs), mpg, colour = factor(am))) + 
      geom_boxplot() +
      stat_summary(fun.data = give.n, geom = "text", fun.y = median,
                   position = position_dodge(width = 0.75))
p

So when I do the below to change the colours, it doesn't work (it gives me only 1 combined number)

stat_summary(fun.data = give.n, geom = "text", fun.y = median,
                   position = position_dodge(width = 0.75), colour =   c("black", "red"))

And when I do the below to add the text "n=" it doesn't work either. (I try to add the "n=" in the function itself, by doing the below:

give.n <- function(x){
      return(c(y = median(x)*1.05, label = paste0("n=",length(x)))) 
    } 

But I get the below error:

 Error: Discrete value supplied to continuous scale
ekad
  • 14,436
  • 26
  • 44
  • 46
debbybeginner
  • 79
  • 1
  • 10

1 Answers1

2

For the colours, you want to add these using scale_colour_manual, so plot call looks like:

p <- 
    ggplot(mtcars, aes(factor(vs), mpg, colour = factor(am))) + 
    geom_boxplot() +
    stat_summary(fun.data = give.n, geom = "text", fun.y = median,
               position = position_dodge(width = 0.75)) +
    scale_colour_manual(values = c("black", "red"))

The answer to adding "n=" is a duplicate of this question: Use stat_summary to annotate plot with number of observations. You need to use data.frame(...) in your give.n function rather than c(...):

give.n <- 
    function(x){
      return(data.frame(y = median(x)*1.05, label = paste0("n=",length(x)))) 
    } 

EDIT: Re comment on changing colours for stat_summary items only, this proved a bit tricky in that I don't think you can have multiple scale_colour_manual layers. However, in this case you can make use of the fill aesthetic for box plots and leave the colour aesthetic for your text geom. To make it cleaner, I've taken the colour and fill aesthetics out of the ggplot(...) call and put these in each geom:

p <- 
    ggplot(mtcars, aes(factor(vs), mpg)) + 
    geom_boxplot(aes(fill = factor(am))) +
    stat_summary(aes(colour = factor(am)), fun.data = give.n, 
                 geom = "text", fun.y = median, position = position_dodge(width = 0.75)) +
    scale_colour_manual(values = c("black", "red"))

Then if you want to specify colours for the box plot fill you can use scale_fill_manual(...)

Community
  • 1
  • 1
Nick F
  • 311
  • 2
  • 8
  • Thank you! somehow I overlooked the post you mentioned. This worked! On a separate note, I wanted to change the colours of the stat_summary items ONLY, that is, I'd like to keep the colours of my boxplot as they are now, BUT have the number of observations be in black and red (for example). Your suggestion changed both. How do I ONLY change the stat_summary items? thanks! – debbybeginner Jan 31 '16 at 01:07
  • @debbybeginner That one was a bit tricky but a solution is to use the fill aesthetic for the boxplot and leave the colour aesthetic for the stat_summary text geom. Answer updated to reflect this. – Nick F Jan 31 '16 at 19:58