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!

1
  • 5
    Could you post a reproducible example of your faceted plot, to get people started? Commented Oct 31, 2012 at 6:11

1 Answer 1

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)
Sign up to request clarification or add additional context in comments.

3 Comments

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?
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.
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 stackoverflow.com/questions/28305151/… 2) getURLContent("http://i.imgur.com/EOc2V.png", .opts=curlOptions(followlocation = TRUE) that option needs to be given from stackoverflow.com/q/25452896/5183434

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.