3

I have created a multiple panel plot using facet_wrap in ggplot2 and would like to add the different images into each panel.

annotation_custom could be used insert an image into ggplot2, but it is the same for all panels.

This is an example to add R logo

library(ggplot2)

# Create dataset

df <- data.frame(
    x = rep(seq(1, 5), times = 2),
    y = rep(seq(1, 5), times = 2),
    z = rep(seq(1, 2), each = 5)
)

img <- readPNG(system.file("img", "Rlogo.png", package="png"))

g <- rasterGrob(img, interpolate=TRUE)


ggplot(df) +
    geom_point(aes(x, y)) +
    annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
    facet_wrap(~z)

img2 is generated from img.

img2 <- img * 0.5

Is it possible to insert different images in ggplot2 (i.e. imgto panel 1 and img2 to panel 2)?

Thanks for any suggestion. Please let me know if my question is not clear.

mpalanco
  • 12,960
  • 2
  • 59
  • 67
Tao Duan
  • 31
  • 1
  • http://stackoverflow.com/questions/32807665/removing-one-tablegrob-when-applied-to-a-box-plot-with-a-facet-wrap?answertab=votes#tab-top might help. (`?annotation_custom` : *This is a special geom intended for use as static annotations that are the same in every panel*) – user20650 Nov 03 '15 at 01:38
  • 1
    yup, using Baptistes funtion `annotation_custom2` from the link above seems to give the control you want `ggplot(df) + geom_point(aes(x, y)) + facet_wrap(~z) + annotation_custom2(g, data=data.frame(z=1))` – user20650 Nov 03 '15 at 01:44

1 Answers1

0

This is how I solved this problem. I wanted a different image (a raster image) in each panel of a ggplot. The number of panels however might change. This is inside a function. Note Baptistes' annotate_custom2() function definitely is cleaner. https://stackoverflow.com/a/44897816/2403645 I can't remember why I could't get that work; I think it was because I would not know ahead of time the axes limits or number of facets.

library(ggplot2)
library(grid)
library(stringr)

# Set up list of images
N <- 6
img.list <- list()
for(i in 1:N) img.list[[i]] <- as.raster(matrix(runif(15), ncol = 5, nrow = 3))

# Make a panel plot in ggplot
df <- data.frame(name=letters[1:N], val=rep(1:N, each=10))
ggplot(df, aes(val, val)) + geom_point() + facet_wrap(~name)

# Get the current viewport tree
a <- current.vpTree()
# Get the names of the children viewports with name panel
# For me, the viewport name of my plot was "layout"; might be different
#   in different situations
b <- names(a$children$layout$children)
# find the names of the panel viewports.
# Change if you want the images somewhere else in the plot (like panel titles)
panel.vp <- b[stringr::str_detect(b, "panel-")]

# NOTE! the panel naming is weird. panel-1-2 is not row 1 column 2.
# it is the next numbers that seem to denote the panel row/column

# set up a viewport for my image; always top left
vp.img <- grid::viewport(x=unit(0.1,"npc"), y=unit(0.8,"npc"), width=unit(0.2, "npc"), just = "left")
# add the images to each facet
for(i in 1:N){
  # checkout viewport for panel i
  grid::seekViewport(panel.vp[i])
  # draw my image
  grid::grid.draw(grid::grobTree(grid::rasterGrob(img.list[[i]]), vp=vp.img))
}

rasters added to each panel

Eli Holmes
  • 656
  • 7
  • 10