Search code examples
rggplot2r-grid

grid package: Save plot of multiple grobs in one object


I'm assembling several grobs in one image. I can save the output to file in RStudio, but how can I assign it to an object inside R?

Here is an example:

library(ggplot2)
library(grid)

#create the plot
plot <- ggplot(mtcars) +
          geom_point(aes(x = disp, y = mpg)) 

#create two grobs
rect <- rectGrob(gp = gpar(alpha = 0.5, col = "white"))
circle <- circleGrob(x = 0.5, y = 0.5, r = 0.2, gp = gpar(fill = "darkred"))


#create the viewport
vipo <- viewport(x = 0.8, y = 0.8, 
                just = c("centre", "centre"),
                width = 0.3, height = 0.3)

I was trying gTree() where I can pass grobs and viewports but the output is wrong:

plot_gtree <- gTree(children = gList(ggplotGrob(plot), rect, circle), vp = vipo)
grid.draw(plot_gtree)

enter image description here

Of course it doesn't know which grob belongs in which viewport.

If I draw it like that it works fine:

grid.draw(ggplotGrob(plot))

pushViewport(vipo)

grid.draw(rect)
grid.draw(circle)

popViewport()

How can I save this as I can save a ggplot?


Solution

  • A couple of options:

    Add it to the plot with annotation_custom:

    plot = plot + annotation_custom(grobTree(rect, circle), 
                                    xmin=300, xmax=400, ymin=25, ymax=30) 
    

    but then you need to specify the x & y coordinates.

    Or add it to the plot gtable:

    g = gtable::gtable_add_grob(x=ggplotGrob(plot),
                                grobs=grobTree(rect, circle, vp=vipo), 
                                t=7, l=5)
    
    grid.newpage(); grid.draw(g)