I am placing multiple plots into one image using gridExtra::grid.arrange
and would like to have the option of saving the combined plot as an object that could be returned from within a function as part of a list of returned objects. Ideally, I would like to do this without printing the plot object.
The code below creates two plots, combines them with grid.arrange
, and attempts to save the result into x
. However, x
evaluates to NULL
and the plot is printed. The documentation for grid.arrange
points me to arrangeGrob
and suggests plotting can be turned off using plot=FALSE
, but I get an error when I try that because FALSE
is not a grob object.
Any suggestions for what I'm not understanding?
# R under development
# Windows 7 (32 bit)
# ggplot2 1.0.0
# gridExtra 0.9.1
p1 <- ggplot(mtcars, aes(x=factor(cyl), y=mpg)) + geom_boxplot()
p2 <- ggplot(mtcars, aes(x=factor(cyl), y=wt)) + geom_boxplot()
x <- gridExtra::grid.arrange(p1, p2)
x
Per the comments, I'm adding this edit. When I try it with arrangeGrob
, I get no output at all.
> gridExtra::arrangeGrob(p1, p2)
> print(gridExtra::arrangeGrob(p1, p2))
Error: No layers in plot
> x <- gridExtra::arrangeGrob(p1, p2)
> x
Error: No layers in plot
The code in your edit does not work properly since you didn't load gridExtra
.
library(gridExtra)
y <- arrangeGrob(p1, p2, ncol = 1)
class(y)
#[1] "gtable" "grob" "gDesc"
grid.draw(y)
Edit: since version 2.0.0, my comment about grid
dependency below is no longer valid, since grid
is now imported.
Edit: With gridExtra version >= 2.0.0, there is no need to attach either package,
p <- ggplot2::qplot(1,1)
x <- gridExtra::arrangeGrob(p, p)
grid::grid.draw(x)
Funny that this was asked so recently - I was running into this problem as well this week and was able to solve it in a bit of a hacky way, but I couldn't find any other solution I was happier with.
Problem 1: ggplotGrob
is not found
I had to make sure ggplot2 is loaded. I don't completely understand what's happening (I admit I don't fully understand imports/depends/attaching/etc), but the following fixes that. I'd be open to feedback if this is very dangerous.
if (!"package:ggplot2" %in% search()) {
suppressPackageStartupMessages(attachNamespace("ggplot2"))
on.exit(detach("package:ggplot2"))
}
Somebody else linked to this blog post and I think that works as well, but from my (non-complete) understanding, this solution is less horrible. I think.
Problem 2: no layers in plot
As you discovered too, fixing that problem allows us to use grid.arrange
, but that returns NULL and doesn't allow saving to an object. So I also wanted to use arrangeGrob
but I also ran into the above error when gridExtra was not already loaded. Applying the fix from problem 1 again doesn't seem to work (maybe the package is getting de-attached too early?). BUT I noticed that calling grid::grid.draw
on the result of arrangeGrob prints it fine without error. So I added a custom class to the output of arrangeGrob and added a generic print method that simply calls grid.draw
f <- function() {
plot <- gridExtra::arrangeGrob(...)
class(plot) <- c("ggExtraPlot", class(plot))
plot
}
print.ggExtraPlot <- function(x, ...) {
grid::grid.draw(x)
}
Hooray, now I can open a fresh R session with no packages explicitly loaded, and I can successfully call a function that creates a grob and print it later!
You can see the code in action in my package on GitHub.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With