Saving a graph with ggsave after using ggplot_build and ggplot_gtable
Asked Answered
C

2

13

I am modifying a graph built with ggplot by altering the data produced by ggplot_build (for a reason similar to Include space for missing factor level used in fill aesthetics in geom_boxplot). As far as I understand the help I found on this topic, I should be able to save the result by applying ggplot_gtable and arrangeGrob before calling ggsave on the results (Saving grid.arrange() plot to file).

However I obtain an error "plot should be a ggplot2 plot", also with this simple reproductible example:

require('ggplot2')
require('gridExtra')
df <- data.frame(f1=factor(rbinom(100, 1, 0.45), label=c("m","w")), 
                  f2=factor(rbinom(100, 1, 0.45), label=c("young","old")),
                  boxthis=rnorm(100))
g <- ggplot(aes(y = boxthis, x = f2, fill = f1), data = df) + geom_boxplot()
dd <- ggplot_build(g)

# Printing the graph works:
print(arrangeGrob(ggplot_gtable(dd)))

# Saving the graph doesn't:
ggsave('test.png',arrangeGrob(ggplot_gtable(dd)))

Can anybody explain why this does not work ? Is there a way to use ggsave after modifying the data by using ggplot_build() ?

(My version of the packages are gridExtra_0.9.1 and ggplot2_0.9.3.1)

Checky answered 23/8, 2013 at 15:51 Comment(0)
S
23

it does not work because ggsave wants an object of class ggplot, while you're passing a grob. arrangeGrob will sometimes trick ggsave in pretending inheritance from ggplot, but only when at least one of the grobs belongs to this class; here, however, you're only passing a gtable.

Perhaps the easiest workaround is to clone ggsave and bypass the class check,

ggsave <- ggplot2::ggsave; body(ggsave) <- body(ggplot2::ggsave)[-2]

Edit: The dev version of ggplot2 no longer requires this hack*, as ggsave now works with any grob.

*PS: this hack works no longer, as arrangeGrob now returns a gtable, and its print method does not draw on a device.

Swinson answered 23/8, 2013 at 16:16 Comment(4)
Thanks. This, in combination with [link] (https://mcmap.net/q/82986/-inserting-a-table-under-the-legend-in-a-ggplot2-and-saving-everything-to-a-file), fixed my problem of saving plots created by 'ggplot2' using 'gtable' with 'ggsave'.Halo
@Swinson I tried your trick with the overwriting ggsave function but it is not working in my case. At the same time, ggplot is still 1.0.1 and the problem is not fixed yet. If I use your method, I create a pdf file using ggsave('test.pdf', arrangeGrob(p1, p2)) but it is corrupted in a way. At the same time the gtable get printed in the console. So something is not properly working.Nubilous
I just updated to gridExtra_2.0.0 and I have ggplot2_1.0.1 installed (which both seem to be the newest version on CRAN). As you state in your update arrangeGrob now returs a gtable, while ggsave still tests the class of the plot object. Do I have to install the development version of ggplot to save a plot done with arrangeGrob?Ddt
Yes, note that a ggplot2 update is meant to be released soon, last time I checked last monthSwinson
S
1

A work around is to plot the gtable object with grid.draw() and then use dev.copy() to transfer the plot to a file.

Remember to use also dev.off() just afterward.

Sapphire answered 7/12, 2015 at 19:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.