2012-09-02 96 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()