2

Say I'm graphing data for 4 people: Alice, Bob, Chuck and Dana. I'm using ggplot2 to make a faceted plot with one facet per person. I also have 4 images on disk: Alice.png, Bob.png, Chuck.png and Dana.png. (obviously this is a synthetic example that would need to scale to more than 4 facets :)

Is there a way I can annotate each facet with the corresponding image, ideally instead of the facet label (although I'd be happy with the image right below the label)? Perhaps something similar to the technique used here: Use image instead of labels in ggplot2 legend ? I've tried reading through the documentation for the various annotate methods but my R-fu is insufficient to the challenge!

Community
  • 1
  • 1
nicolaskruchten
  • 26,384
  • 8
  • 83
  • 101

1 Answers1

6

Not very elegant, but you can add grobs on top of the strip labels,

library(ggplot2)

d <- expand.grid(x=1:2,y=1:2, f=letters[1:2])
p <- qplot(x,y,data=d) + facet_wrap(~f)

g <- ggplot_gtable(ggplot_build(p))

library(gtable)
library(RCurl)
library(png)
shark <- readPNG(getURLContent("http://i.imgur.com/EOc2V.png"))
tiger <- readPNG(getURLContent("http://i.imgur.com/zjIh5.png"))

strips <- grep("strip", g$layout$name)
new_grobs <- list(rasterGrob(shark, width=1, height=1),
                  rasterGrob(tiger, width=1, height=1))
g <- with(g$layout[strips,],
          gtable_add_grob(g, new_grobs,
                          t=t, l=l, b=b, r=r, name="strip_predator") )        
grid.draw(g)

Edit: you can also replace directly the grobs,

strips <- grep("strip", names(g$grobs))
new_grobs <- list(rectGrob(gp=gpar(fill="red", alpha=0.2)),
                  rectGrob(gp=gpar(fill="blue", alpha=0.2)))
g$grobs[strips] <- new_grobs
grid.draw(g)
baptiste
  • 75,767
  • 19
  • 198
  • 294
  • Ah ok, I see what you're doing there... the only challenge is to get my new_grobs list in the same order as ggplot decided to order my facets, right? – nicolaskruchten Oct 31 '12 at 17:04
  • that shouldn't be too hard; an alternative would be to define your own custom `element` theme function to use as strips, which would look up a particular iamge corresponding to the text. – baptiste Nov 01 '12 at 05:51
  • 1
    Hello from almost a decade away. For anyone like me, there are two changes that need to be made: 1) `grid::rasterGrob`, ggplot doesn't automatically load this package from https://stackoverflow.com/questions/28305151/rastergrob-function-not-found-in-search#comment44964352_28305151 2) `getURLContent("http://i.imgur.com/EOc2V.png", .opts=curlOptions(followlocation = TRUE)` that option needs to be given from https://stackoverflow.com/q/25452896/5183434 – Jeff Sep 20 '22 at 19:13