2012-09-02 24 views
16

Tengo una lista, p, donde cada elemento de p es una lista de objetos de trazado ggplot2.Imprimir múltiples ggplots en un solo PDF, varias gráficas por página

me gustaría dar salida a un solo PDF que contiene todas las parcelas en p tal que las parcelas en p[[1]] están en la página 1, las parcelas en p[[2]] están en la página 2, etc. ¿Cómo puede hacer esto?

Aquí hay un código de ejemplo para proporcionarle la estructura de datos con la que estoy trabajando: disculpas por las tramas aburridas, seleccioné variables al azar.

require(ggplot2) 
p <- list() 

cuts <- unique(diamonds$cut) 
for(i in 1:length(cuts)){ 
    p[[i]] <- list() 
    dat <- subset(diamonds, cut==cuts[i]) 
    p[[i]][[1]] <- ggplot(dat, aes(price,table)) + geom_point() + 
     opts(title=cuts[i]) 
    p[[i]][[2]] <- ggplot(dat, aes(price,depth)) + geom_point() + 
     opts(title=cuts[i]) 
} 
+0

Aquí hay un posible comienzo: 'require (gridExtra); do.call ("grid.arrange", p [[i]]) '. Eso trazará los objetos ggplot en p [[i]] en un solo dispositivo, organizándolos muy bien. – Michael

+0

Consulte también el paquete gridExtra. Creo que eso debería hacerte llegar hasta el final – chandler

Respuesta

15

Esta solución es independiente de si las longitudes de las listas en la lista p son diferentes.

library(gridExtra) 

pdf("plots.pdf", onefile = TRUE) 
for (i in seq(length(p))) { 
    do.call("grid.arrange", p[[i]]) 
} 
dev.off() 

Debido a la función onefile = TRUEpdf guarda todos los gráficos que aparecen secuencialmente en el mismo archivo (una página para un gráfico).

+0

¡Esto funcionó perfectamente, gracias! – Michael

+1

Para mí, esto da como resultado un PDF dañado que no se puede abrir. Las tramas se ven bien individualmente. ¿Algun consejo? –

+0

opts() no funcionó para mí en 'ggplot2_2.2.1' y' R versión 3.3.2'. Use '+ ggtitle (cuts [i])' en su lugar. –

2

Aquí hay una solución, pero no me gusta especialmente que:

ggsave("test.pdf", do.call("marrangeGrob", c(unlist(p,recursive=FALSE),nrow=2,ncol=1)))

El problema es que se basa en la existencia de la misma cantidad de parcelas en cada grupo. Si all(sapply(p, length) == 2) fuera falso, se rompería.

7

Aquí hay una versión más simple de la solución de Sven para los principiantes R que de otra manera utilizarían ciegamente las listas do.call y anidadas que no necesitan ni entienden. Tengo evidencia empírica. :)

library(ggplot2) 
library(gridExtra) 

pdf("plots.pdf", onefile = TRUE) 
cuts <- unique(diamonds$cut) 
for(i in 1:length(cuts)){ 
    dat <- subset(diamonds, cut==cuts[i]) 
    top.plot <- ggplot(dat, aes(price,table)) + geom_point() + 
     opts(title=cuts[i]) 
    bottom.plot <- ggplot(dat, aes(price,depth)) + geom_point() + 
     opts(title=cuts[i]) 
    grid.arrange(top.plot, bottom.plot) 
} 
dev.off() 
Cuestiones relacionadas