webentwicklung-frage-antwort-db.com.de

Drucken mehrerer ggplots in einem einzigen pdf, mehrere plots pro Seite

Ich habe eine Liste, p, in der jedes Element von p eine Liste von Plot-Objekten von ggplot2 ist.

Ich möchte ein einzelnes PDF mit allen Plots in p ausgeben, so dass die Plots in p[[1]] auf Seite 1, die Plots in p[[2]] auf Seite 2 usw. sind. Wie kann ich das tun?

Hier ist ein Beispielcode, mit dem Sie die Datenstruktur angeben können, mit der ich arbeite. Ich entschuldige mich für die langweiligen Diagramme und wählte zufällig Variablen aus.

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])
}
20
Michael

Diese Lösung ist unabhängig davon, ob die Länge der Listen in der Liste p unterschiedlich ist.

library(gridExtra)

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

Aufgrund von onefile = TRUE speichert die Funktion pdf alle Grafiken, die nacheinander in derselben Datei erscheinen (eine Seite für eine Grafik).

18
Sven Hohenstein

Hier ist eine einfachere Version von Svens Lösung für R-Anfänger, die sonst die do.call- und verschachtelten Listen verwenden würden, die sie weder brauchen noch verstehen. Ich habe empirische Beweise. :)

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()
10
chris

Hier ist eine Lösung, die mir aber nicht besonders gefällt:

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

Das Problem besteht darin, dass in jeder Gruppe die gleiche Anzahl von Parzellen vorhanden ist. Wenn all(sapply(p, length) == 2) falsch wäre, würde es brechen.

5
Michael

Hier ist eine Funktion, die auf Svens Ansatz basiert, einschließlich der roxygen2 -Dokumentation und eines Beispiels.

#' Save list of ggplot2 objects to single pdf
#'
#' @param list (list) List of ggplot2 objects.
#' @param filename (chr) What to call the pdf.
#'
#' @return Invisible NULL.
#' @export
#'
#' @examples
#' #plot histogram of each numeric variable in iris
#' list_iris = map(names(iris[-5]), ~ggplot(iris, aes_string(.)) + geom_histogram())
#' #save to a single pdf
#' GG_save_pdf(list_iris, "test.pdf")
GG_save_pdf = function(list, filename) {
  #start pdf
  pdf(filename)

  #loop
  for (p in list) {
    print(p)
  }

  #end pdf
  dev.off()

  invisible(NULL)
}
2
Deleet

Ich habe einige dieser Lösungen ausprobiert, jedoch ohne Erfolg. Ich recherchierte ein bisschen weiter und fand eine Lösung, die für mich perfekt funktionierte. Alle meine Grafiken werden in einer einzigen PDF-Datei gespeichert, jedes Diagramm auf einer Seite.

library(ggplot2)


pdf("allplots.pdf",onefile = TRUE)
for(i in glist){
   tplot <- ggplot(df, aes(x = as.factor(class), y = value))
   print(tplot)
}
dev.off()
1
Pedro Henrique

Eine nette Lösung ohne das gridExtra-Paket:

library(plyr)
library(ggplot2)

li = structure(p, class = c("gglist", "ggplot"))
print.gglist = function(x, ...) l_ply(x, print, ...)
ggsave(li, file = "test.pdf")
0
fc9.30