web-dev-qa-db-fra.com

Imprimer plusieurs ggplots dans un seul pdf, plusieurs tracés par page

J'ai une liste, p, où chaque élément de p est une liste d'objets de tracé ggplot2.

Je voudrais sortir un seul fichier PDF contenant tous les tracés dans p tels que les tracés dans p[[1]] soient à la page 1, les tracés dans p[[2]] à la page 2, etc. Comment puis-je faire cela?

Voici un exemple de code pour vous fournir la structure de données sur laquelle je travaille - des excuses pour les tracés ennuyeux, j'ai choisi des variables au hasard.

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

Cette solution est indépendante du fait que les longueurs des listes de la liste p soient différentes.

library(gridExtra)

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

En raison de onefile = TRUE, la fonction pdf enregistre tous les graphiques apparaissant de manière séquentielle dans le même fichier (une page pour un graphique).

18
Sven Hohenstein

Voici une version simplifiée de la solution de Sven pour les débutants de R qui utiliseraient aveuglément les listes do.call et imbriquées dont ils n'avaient ni besoin ni la compréhension. J'ai des preuves empiriques. :)

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

Voici une fonction basée sur l'approche de Sven, incluant la documentation roxygen2 et un exemple.

#' 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

J'ai essayé certaines de ces solutions mais sans succès. J'ai cherché un peu plus et trouvé une solution qui a parfaitement fonctionné pour moi. Il enregistre tous mes graphiques dans un seul fichier pdf, chaque graphique sur une page.

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

Une solution intéressante sans le package gridExtra:

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