store arrangeGrob to object, does not create printable object
The gridExtra
package has been updated recently thereby changing how arrangeGrob
works internally and what kind of object it returns (now a gtable
).
You need to call grid.draw
:
grid.draw(y)
Edit: do not use plot()
as initially suggested; it will add a grey background, and is only meant to be used for debugging gtables.
Store output from gridExtra::grid.arrange into an object
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)
Saving grid.arrange() plot to file
grid.arrange
draws directly on a device. arrangeGrob
, on the other hand, doesn't draw anything but returns a grob g
, that you can pass to ggsave(file="whatever.pdf", g)
.
The reason it works differently than with ggplot objects, where by default the last plot is being saved if not specified, is that ggplot2 invisibly keeps track of the latest plot, and I don't think grid.arrange
should mess with this counter private to the package.
using ggsave and arrangeGrob after updating gridExtra to 2.0.0
Pascal brought me finally to the idea to check for the differences between ggplot 1.0.1
and ggplot 1.0.1.9003
, since I don't want to or force the development version of ggplot
.
So my idea is a function which will be executed within each script which overwrites the default ggsave
function.
I tested it now a little, if there are any bugs or so, please let me know. But the way I do it now it works so far.
repairGgsave <- function() {
ggplot_version <-
compareVersion(as.character(packageVersion('ggplot2')),
'1.0.1.9003')
gridextra_version <-
compareVersion(as.character(packageVersion('gridExtra')),
'0.9.1')
if(gridextra_version > 0) {
if(ggplot_version <= 0) {
ggsave <- function(filename, plot = last_plot(),
device = NULL, path = NULL, scale = 1,
width = NA, height = NA, units = c("in", "cm", "mm"),
dpi = 300, limitsize = TRUE, ...) {
dev <- plot_dev(device, filename, dpi = dpi)
dim <- plot_dim(c(width, height), scale = scale, units = units,
limitsize = limitsize)
if (!is.null(path)) {
filename <- file.path(path, filename)
}
dev(file = filename, width = dim[1], height = dim[2], ...)
on.exit(utils::capture.output(grDevices::dev.off()))
grid.draw(plot)
invisible()
}
assign("ggsave", ggsave, .GlobalEnv)
plot_dim <<- function(dim = c(NA, NA), scale = 1, units = c("in", "cm", "mm"),
limitsize = TRUE) {
units <- match.arg(units)
to_inches <- function(x) x / c(`in` = 1, cm = 2.54, mm = 2.54 * 10)[units]
from_inches <- function(x) x * c(`in` = 1, cm = 2.54, mm = 2.54 * 10)[units]
dim <- to_inches(dim) * scale
if (any(is.na(dim))) {
if (length(grDevices::dev.list()) == 0) {
default_dim <- c(7, 7)
} else {
default_dim <- dev.size() * scale
}
dim[is.na(dim)] <- default_dim[is.na(dim)]
dim_f <- prettyNum(from_inches(dim), digits = 3)
message("Saving ", dim_f[1], " x ", dim_f[2], " ", units, " image")
}
if (limitsize && any(dim >= 50)) {
stop("Dimensions exceed 50 inches (height and width are specified in '",
units, "' not pixels). If you're sure you a plot that big, use ",
"`limitsize = FALSE`.", call. = FALSE)
}
dim
}
plot_dev <<- function(device, filename, dpi = 300) {
if (is.function(device))
return(device)
eps <- function(...) {
grDevices::postscript(..., onefile = FALSE, horizontal = FALSE,
paper = "special")
}
devices <- list(
eps = eps,
ps = eps,
tex = function(...) grDevices::pictex(...),
pdf = function(..., version = "1.4") grDevices::pdf(..., version = version),
svg = function(...) grDevices::svg(...),
emf = function(...) grDevices::win.metafile(...),
wmf = function(...) grDevices::win.metafile(...),
png = function(...) grDevices::png(..., res = dpi, units = "in"),
jpg = function(...) grDevices::jpeg(..., res = dpi, units = "in"),
jpeg = function(...) grDevices::jpeg(..., res = dpi, units = "in"),
bmp = function(...) grDevices::bmp(..., res = dpi, units = "in"),
tiff = function(...) grDevices::tiff(..., res = dpi, units = "in")
)
if (is.null(device)) {
device <- tolower(tools::file_ext(filename))
}
if (!is.character(device) || length(device) != 1) {
stop("`device` must be NULL, a string or a function.", call. = FALSE)
}
dev <<- devices[[device]]
if (is.null(dev)) {
stop("Unknown graphics device '", device, "'", call. = FALSE)
}
dev
}
}
}
}
It basically overwrites the ggsave
and creates two new functions from the development version.
After executing the function everything seems to work.
problems with arrangeGrob under R version 3.2.2
From Kev's comment:
There has been a rewrite of gridExtra, that is not (fully) backward
compatible - may be the issue. Have a look at the new wiki
cran.r-project.org/web/packages/gridExtra/vignettes/… . Try changing
main to top – user20650
arrangeGrob with gtable objects
Use function arrangeGrob()
to save both plots as object.
theplot <- arrangeGrob(gA, gB, ncol=1)
how do I get rid of random background grid from arrangeGrob
arrangeGrob()
now returns a gtable, which you should draw with grid.draw()
, not plot()
.
grid.draw(y)
yields
To get rid of artefacts from past plots (as per above update) use grid.newpage()
.
Assign grid.arrange to object
If you look at the source code for grid.arrange
, it is simply a wrapper for arrangeGrob
function (..., as.table = FALSE, clip = TRUE, main = NULL, sub = NULL,
left = NULL, legend = NULL, newpage = TRUE)
{
if (newpage)
grid.newpage()
grid.draw(arrangeGrob(..., as.table = as.table, clip = clip,
main = main, sub = sub, left = left, legend = legend))
}
Therefore
require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip()
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip()
gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
gA$widths[2:5] <- as.list(maxWidth)
gB$widths[2:5] <- as.list(maxWidth)
x <- arrangeGrob(gA, gB, ncol=1)
y <- arrangeGrob(gA, gB, ncol=1)
grid.arrange(x, y, ncol=2)
will work
Cannot disable R markdown output from gridExtra (additional comment)
don't print()
, grid.arrange()
draws by itself. If you want to store the result and then draw it, use arrangeGrob()+grid.draw()
Related Topics
Extract Date from Given String in R
Error in Na.Fail.Default: Missing Values in Object - But No Missing Values
Text Mining R Package & Regex to Handle Replace Smart Curly Quotes
Subset Dataframe Based on Posixct Date and Time Greater Than Datetime Using Dplyr
Back-To-Back Barplot with Independent Axes R
Purrr:Map and Glm - Issues with Call
How to Make Stacked Barplot with Ggplot2
Is There a Difference Between the R Functions Fitted() and Predict()
How to Prep Transaction Data into Basket for Arules
How to Get Name from a Value in an R Vector with Names
How to Get the Min/Max Possible Numeric
How to Automatically Load Data in an R Package
Using Grep to Subset Rows from a Data.Table, Comparing Row Content
Use Sprintf() to Add Trailing Zeros
R Data.Table Fread Command:How to Read Large Files with Irregular Separators