Store Arrangegrob to Object, Does Not Create Printable Object

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)

resulting plot

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)

Sample Image

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

fine plot

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

Sample Image

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



Leave a reply



Submit