我想使用ggplot2包並排放置兩個圖,即作par(mfrow=c(1,2))
的等效項。 html
例如,我但願如下兩個圖以相同的比例並排顯示。 web
x <- rnorm(100) eps <- rnorm(100,0,.2) qplot(x,3*x+eps) qplot(x,2*x+eps)
我須要將它們放在相同的data.frame中嗎? app
qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()
是的,您須要適當地安排數據。 一種方法是: ide
X <- data.frame(x=rep(x,2), y=c(3*x+eps, 2*x+eps), case=rep(c("first","second"), each=100)) qplot(x, y, data=X, facets = . ~ case) + geom_smooth()
我確信在plyr或重塑方面會有更好的技巧-我仍然尚未真正掌握Hadley的全部這些強大功能。 函數
使用重塑包裝,您能夠執行如下操做。 post
library(ggplot2) wide <- data.frame(x = rnorm(100), eps = rnorm(100, 0, .2)) wide$first <- with(wide, 3 * x + eps) wide$second <- with(wide, 2 * x + eps) long <- melt(wide, id.vars = c("x", "eps")) ggplot(long, aes(x = x, y = value)) + geom_smooth() + geom_point() + facet_grid(.~ variable)
更新:這個答案很老了。 如今推薦使用gridExtra::grid.arrange()
。 若是可能有用,我將其留在這裏。 ui
blog (see post for application instructions) 斯蒂芬·特納arrange()
Stephen Turner arrange()
在博客上發佈了arrange()
函數 (有關應用說明,請參閱帖子) this
vp.layout <- function(x, y) viewport(layout.pos.row=x, layout.pos.col=y) arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE) { dots <- list(...) n <- length(dots) if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)} if(is.null(nrow)) { nrow = ceiling(n/ncol)} if(is.null(ncol)) { ncol = ceiling(n/nrow)} ## NOTE see n2mfrow in grDevices for possible alternative grid.newpage() pushViewport(viewport(layout=grid.layout(nrow,ncol) ) ) ii.p <- 1 for(ii.row in seq(1, nrow)){ ii.table.row <- ii.row if(as.table) {ii.table.row <- nrow - ii.table.row + 1} for(ii.col in seq(1, ncol)){ ii.table <- ii.p if(ii.p > n) break print(dots[[ii.table]], vp=vp.layout(ii.table.row, ii.col)) ii.p <- ii.p + 1 } } }
基於grid.arrange
的解決方案的一個缺點是,正如大多數期刊所要求的那樣,它們使用字母(A,B等)標記圖表變得困難。 spa
我寫了cowplot包來解決這個(以及其餘一些)問題,特別是函數plot_grid()
: code
library(cowplot) iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + geom_boxplot() + theme_bw() iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) + geom_density(alpha = 0.7) + theme_bw() + theme(legend.position = c(0.8, 0.8)) plot_grid(iris1, iris2, labels = "AUTO")
plot_grid()
返回的對象是另外一個ggplot2對象,您能夠像往常同樣使用ggsave()
保存它:
p <- plot_grid(iris1, iris2, labels = "AUTO") ggsave("plot.pdf", p)
另外,您也可使用cowplot功能save_plot()
這大約是一個瘦包裝ggsave()
能夠很容易獲得結合地塊,如正確的尺寸:
p <- plot_grid(iris1, iris2, labels = "AUTO") save_plot("plot.pdf", p, ncol = 2)
( save_plot()
ncol = 2
參數告訴save_plot()
並排有兩個圖,而save_plot()
使保存的圖像寬兩倍。)
有關如何在網格中佈置圖的更深刻描述,請參見此插圖。 還有一個小插圖,說明如何使用共享的圖例進行繪製。
一個常常引發混淆的地方是Cowplot軟件包更改了默認的ggplot2主題。 該程序包具備這種功能,由於它最初是爲內部實驗室使用而編寫的,咱們從不使用默認主題。 若是這引發問題,則可使用如下三種方法之一來解決它們:
1.爲每一個圖手動設置主題。 我認爲始終爲每一個情節指定一個特定主題是一個好習慣,就像我在上面的示例中使用+ theme_bw()
。 若是指定特定主題,則默認主題可有可無。
2.將默認主題恢復爲ggplot2默認。 您可使用一行代碼來作到這一點:
theme_set(theme_gray())
3.調用Cowplot函數而不附加包裝。 您也不能調用library(cowplot)
或require(cowplot)
,而是經過在cowplot::
前面加cowplot::
來調用Cowplot函數。 例如,上面使用ggplot2默認主題的示例將變爲:
## Commented out, we don't call this # library(cowplot) iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + geom_boxplot() iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) + geom_density(alpha = 0.7) + theme(legend.position = c(0.8, 0.8)) cowplot::plot_grid(iris1, iris2, labels = "AUTO")
更新:
gridExtra
包中的函數grid.arrange()
將合併多個圖; 這就是您將兩個並排放置的方式。
require(gridExtra) plot1 <- qplot(1) plot2 <- qplot(1) grid.arrange(plot1, plot2, ncol=2)
當兩個圖都不基於相同的數據時,例如,若是您要繪製不一樣的變量而不使用reshape()時,這頗有用。
這會將輸出做爲反作用繪製。 要將反作用打印到文件,請指定設備驅動程序(例如pdf
, png
等),例如
pdf("foo.pdf") grid.arrange(plot1, plot2) dev.off()
或者,將arrangeGrob()
與ggsave()
結合使用,
ggsave("foo.pdf", arrangeGrob(plot1, plot2))
這等效於使用par(mfrow = c(1,2))
繪製兩個不一樣的圖。 這不只節省了整理數據的時間,並且在須要兩個不一樣的圖時頗有必要。
構面有助於爲不一樣的組繪製類似的圖。 下面在下面的許多答案中都指出了這一點,但我想經過與上述圖表等效的示例來突出此方法。
mydata <- data.frame(myGroup = c('a', 'b'), myX = c(1,1)) qplot(data = mydata, x = myX, facets = ~myGroup) ggplot(data = mydata) + geom_bar(aes(myX)) + facet_wrap(~myGroup)
該plot_grid
在功能cowplot
是值得檢查做爲替代grid.arrange
。 請參見下面@ claus-wilke的答案和此插圖 ,以瞭解等效的方法; 但此功能可根據此小插圖更好地控制繪圖位置和大小。