Guardar un gráfico con ggsave después de usar ggplot_build y ggplot_gtable

Estoy modificando un gráfico creado con ggplot alterando los datos producidos por ggplot_build (por una razón similar a Incluir espacio para el nivel de factor faltante utilizado en la estética de relleno en geom_boxplot ). Por lo que entiendo la ayuda que encontré sobre este tema, debería ser capaz de guardar el resultado aplicando ggplot_gtable y arrangeGrob antes de llamar a ggsave en los resultados ( Guardando grid.arrange () ttwig al archivo ).

Sin embargo, obtengo un error “la ttwig debe ser una ttwig ggplot2“, también con este sencillo ejemplo reproductivo:

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))) 

¿Alguien puede explicar por qué esto no funciona? ¿Hay alguna manera de usar ggsave después de modificar los datos usando ggplot_build ()?

(Mi versión de los paquetes es gridExtra_0.9.1 y ggplot2_0.9.3.1)

no funciona porque ggsave quiere un objeto de la clase ggplot , mientras estás pasando un grob. arrangeGrob a veces ggsave a ggsave para simular la herencia de ggplot , pero solo cuando al menos uno de los grobs pertenezca a esta clase; aquí, sin embargo, solo estás pasando una gtable .

Tal vez la solución más fácil es clonar ggsave y eludir el control de clase,

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

Editar: La versión de desarrollo de ggplot2 ya no requiere este hack *, ya que ggsave ahora funciona con cualquier grob .

* PD: este truco ya no funciona, ya que arrangeGrob ahora devuelve un tabla y su método de impresión no se basa en un dispositivo.

Una solución alternativa es trazar el objeto tablable con grid.draw () y luego usar dev.copy () para transferir la gráfica a un archivo.

Recuerde usar también dev.off () justo después.