Печать нескольких ggplots в один PDF, несколько графиков на странице
У меня есть список, p
где каждый элемент p
список объектов ggplot2
Я хотел бы вывести один PDF-файл, содержащий все графики в p
такой, что участки в p[[1]]
находятся на странице 1, участки в p[[2]]
на странице 2 и т. д. Как я могу это сделать?
Вот некоторый пример кода, чтобы предоставить вам структуру данных, с которой я работаю - извинения за скучные графики, я выбрал переменные наугад.
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])
}
5 ответов
Это решение не зависит от длины списков в списке p
разные.
library(gridExtra)
pdf("plots.pdf", onefile = TRUE)
for (i in seq(length(p))) {
do.call("grid.arrange", p[[i]])
}
dev.off()
Потому что onefile = TRUE
функция pdf
сохраняет всю графику, появляющуюся последовательно в одном и том же файле (одна страница для одной графики).
Вот наиболее элегантное решение для экспорта списка объектов ggplot в один файл pdf с использованием ggplot2::ggsave()
а также gridExtra::marrangeGrob()
.
library(ggplot2)
library(gridExtra)
Допустим, вы создали несколько графиков, используя lapply()
p <- lapply(names(mtcars), function(x) {
ggplot(mtcars, aes_string(x)) +
geom_histogram()
})
Сохранить список p
участки:
ggsave(
filename = "plots.pdf",
plot = marrangeGrob(p, nrow=1, ncol=1),
width = 15, height = 9
)
Вот более простая версия решения Свена для начинающих R, которые иначе слепо использовали бы do.call и вложенные списки, которые им не нужны и не понятны. У меня есть эмпирические доказательства.:)
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()
Я пробовал некоторые из этих решений, но безуспешно. Я немного больше исследовал и нашел решение, которое отлично сработало для меня. Он сохраняет всю мою графику в одном файле PDF, каждый график на одной странице.
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()
Вот одно из решений, но мне оно не особо нравится:
ggsave("test.pdf", do.call("marrangeGrob", c(unlist(p,recursive=FALSE),nrow=2,ncol=1)))
Проблема заключается в том, что в каждой группе одинаковое количество участков. Если all(sapply(p, length) == 2)
были бы ложными, тогда это сломалось бы.
Решение, которое помогло мне ggpubr
пакет (пакет на Github, код для установки: devtools::install_github("kassambara/ggpubr")
).
Допустим, у вас есть 4 графика p1, p2, p3 и p4.
library(ggpubr)
multi.page <- ggarrange(p1,p2,p3,p4, nrow=1, ncol=1) # for one plot per page
multi.page[[1]] # for seeing the first plot
ggexport(multi.page, filename="my-plots.pdf")
Еще примеры ggpubr
используйте: http://www.sthda.com/english/articles/24-ggpubr-publication-ready-plots/81-ggplot2-easy-way-to-mix-multiple-graphs-on-the-same-page/
Вот функция, основанная на подходе Свена, включая документацию roxygen2 и пример.
#' 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)
}
Хорошее решение без 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")