37

Possible Duplicate:
Creating a facet_wrap plot with ggplot2 with different annotations in each plot
Add text to a faceted plot in ggplot2 with dates on X axis

Occasionally when faceting data in ggplot, I think it would be nice to annotate each facet with the number of observations that fell into each facet. This is particularly important when faceting may result in relatively few observations per facet.

What would be the best / simplest way to add an "n=X" to each facet of this plot?

require(ggplot2)
mms <- data.frame(deliciousness = rnorm(100),
                  type=sample(as.factor(c("peanut", "regular")), 100, replace=TRUE),
                  color=sample(as.factor(c("red", "green", "yellow", "brown")), 100, replace=TRUE))


plot <- ggplot(data=mms, aes(x=deliciousness)) + geom_density() + facet_grid(type ~ color)
Community
  • 1
  • 1
Peter
  • 4,219
  • 4
  • 28
  • 40
  • http://stackoverflow.com/questions/2050610/creating-a-facet-wrap-plot-with-ggplot2-with-different-annotations-in-each-plot – Andy Nov 05 '12 at 21:04
  • http://stackoverflow.com/questions/11458349/add-text-to-a-faceted-plot-in-ggplot2-with-dates-on-x-axis – Geek On Acid Nov 05 '12 at 21:13
  • up-voted for a including the image and reproducible data (cf. "creating a facet_wrap...") – flies Oct 26 '17 at 14:13

1 Answers1

51

It looks like this has been asked before, and I failed initially to see how they connected. I'm answering this here, but leaving it as not accepted in case someone has something more elegant. Also, the n = foo is a common enough case, that hopefully someone will get some use out of this question even though it's a bit duplicative.

require(ggplot2)
require(plyr)
mms <- data.frame(deliciousness = rnorm(100),
                  type=sample(as.factor(c("peanut", "regular")), 
                              100, replace=TRUE),
                  color=sample(as.factor(c("red", "green", "yellow", "brown")), 
                              100, replace=TRUE))


mms.cor <- ddply(.data=mms, 
                 .(type, color), 
                 summarize, 
                 n=paste("n =", length(deliciousness)))

plot <- ggplot(data=mms, aes(x=deliciousness)) + 
          geom_density() + 
          facet_grid(type ~ color) + 
          geom_text(data=mms.cor, aes(x=1.8, y=5, label=n), 
                    colour="black", inherit.aes=FALSE, parse=FALSE)

plot

The output

joran
  • 169,992
  • 32
  • 429
  • 468
Peter
  • 4,219
  • 4
  • 28
  • 40
  • 2
    Thanks - this provided an answer that I hadn't found elsewhere – Ed G Apr 30 '13 at 09:27
  • 4
    Even if technically a duplicate, this example has the merit of being simpler and is going to the core of the solution. The OP's title is clearer as well imho. – jjap Jan 17 '17 at 14:56
  • Got a bit of a simpler solution - avoids having to define `mms.cor`. Within `geom_text`, define the data as `data = plyr::count(mms, vars = c("deliciousness"))`. Caveat being I've only tested this with facets for only one variable, not two. – spops Oct 22 '19 at 14:41
  • 1
    Thanks, helpful Q&A indeed! Inspired by @spops comment, I found a solution that would work on this data frame, facetting on two variables, without the need for `mms.cor`: `geom_text(data=plyr::count(mms, vars = c("type","color")), aes(x=1.8, y=5, label=paste0("N=",freq)), colour="black", inherit.aes=FALSE, parse=FALSE)` – bug313 Feb 04 '20 at 14:56