2012-09-02 54 views
16

我有一个列表p,其中p的每个元素都是ggplot2绘图对象的列表。将多个ggplots打印成一个pdf,每页有多个图

我想输出包含p这样所有的地块,在p[[1]]情节是第1页单一PDF,在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]) 
} 
+0

这里有一个潜在的开始:'require(gridExtra); do.call( “grid.arrange”,P [[I]])'。这将在单个设备中绘制p [[i]中的ggplot对象,并很好地排列它们。 – Michael

+0

也看看gridExtra包。我认为这应该会让你获得最大的成绩 – chandler

回答

15

此解决方案与列表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的保存在同一文件(一个页面一个图形)中相继出现的所有的图形。

+0

这很好,谢谢! – Michael

+1

对我而言,这会导致无法打开的PDF损坏。这些情节单独看起来很好。有小费吗? –

+0

opts()在'ggplot2_2.2.1'和'R version 3.3.2'上不适用于我。改为使用'+ ggtitle(剪切[i])'。 –

2

这里有一个解决办法,但我特别不喜欢它:

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

的问题是,它依赖于有是相同数量的各组地块。如果all(sapply(p, length) == 2)是错误的,那么它会中断。

7

这是一个更简单的Sven解决方案,适用于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()