与ggplot2并排绘图

我想使用ggplot2软件包并排放置两个图,即做相当于par(mfrow=c(1,2))

例如,我希望以下两个地块以相同的比例并排显示。

 x <- rnorm(100) eps <- rnorm(100,0,.2) qplot(x,3*x+eps) qplot(x,2*x+eps) 

我需要把它们放在相同的data.frame?

 qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth() 

任何ggplots并排(或n个网格)

gridExtra包中的函数grid.arrange()将组合多个图; 这是你如何把两个并排。

 require(gridExtra) plot1 <- qplot(1) plot2 <- qplot(1) grid.arrange(plot1, plot2, ncol=2) 

如果两个图不基于相同的数据,例如如果要在不使用reshape()的情况下绘制不同的variables,这是非常有用的。

这将把输出作为副作用。 要将副作用打印到文件,请指定设备驱动程序(如pdfpng等),例如

 pdf("foo.pdf") grid.arrange(plot1, plot2) dev.off() 

或者,与ggsave()结合使用ggsave()

 ggsave("foo.pdf", arrangeGrob(plot1, plot2)) 

这相当于使用par(mfrow = c(1,2))创build两个不同的地块。 这不仅节省了安排数据的时间,而且当你需要两个不相似的地块时也是必要的。


附录:使用分面

方面有助于为不同的团体制作类似的情节。 下面的许多答案都指出了这一点,但我想用相当于上述图表的例子来强调这种方法。

 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的替代scheme, grid.arrangeplot_grid函数值得检查。 请参阅下面的@ claus-wilke和这个小插曲的回答,以获取相同的方法。 但是该function可以根据这个小插图对绘图位置和大小进行更精细的控制。

我从来没有喜欢基于grid.arrange的解决scheme,因为它们使得很难用字母(A,B等)来标注这些地块,正如大多数期刊所要求的那样。 用grid.arrangealignment图也很困难。

我写了cowplot包来解决这些问题,特别是函数plot_grid()

 require(cowplot) plot1 <- qplot(1) plot2 <- qplot(1) plot_grid(plot1, plot2, align='h', labels=c('A', 'B')) 

有关plot_grid()的更深入的描述,请参阅此小插图。

您可以使用Winston Chang的R食谱中的以下多function函数

 multiplot(plot1, plot2, cols=2) 

 multiplot <- function(..., plotlist=NULL, cols) { require(grid) # Make a list from the ... arguments and plotlist plots <- c(list(...), plotlist) numPlots = length(plots) # Make the panel plotCols = cols # Number of columns of plots plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols # Set up the page grid.newpage() pushViewport(viewport(layout = grid.layout(plotRows, plotCols))) vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) # Make each plot, in the correct location for (i in 1:numPlots) { curRow = ceiling(i/plotCols) curCol = (i-1) %% plotCols + 1 print(plots[[i]], vp = vplayout(curRow, curCol )) } } 

是的,你需要适当地安排你的数据。 一种方法是这样的:

 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() 

我相信有更好的技巧或重塑 – 我仍然不是真的要加快哈德利所有这些强大的包裹。

使用重塑包你可以做这样的事情。

 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) 

Stephen Turner 在Getting Genetics Done博客上发布了arrange()函数 (请参阅post了解应用程序说明); 但是build议使用grid.arrange() ,请参阅下面的注释)

 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 } } } 

上面的解决scheme可能不是有效的,如果你想绘制多个ggplot图使用循环(例如,这里问: 在ggplot中创build多个图与不同的Y轴值使用循环 ),这是分析未知的期望的步骤或大的)数据集(例如,当你想绘制一个数据集中的所有variables的计数)。

下面的代码显示了如何使用上面提到的“multiplot()”,它的来源如下: http : //www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_ (ggplot2 ) :

 plotAllCounts <- function (dt){ plots <- list(); for(i in 1:ncol(dt)) { strX = names(dt)[i] print(sprintf("%i: strX = %s", i, strX)) plots[[i]] <- ggplot(dt) + xlab(strX) + geom_point(aes_string(strX),stat="count") } columnsToPlot <- floor(sqrt(ncol(dt))) multiplot(plotlist = plots, cols = columnsToPlot) } 

现在运行该函数 – 获取在一页上使用ggplot打印的所有variables的Counts

 dt = ggplot2::diamonds plotAllCounts(dt) 

有一点要注意的是:
使用aes(get(strX)) ,在使用ggplot ,通常在循环中使用aes(get(strX)) ,而在上面的代码中不使用aes_string(strX)将不绘制所需的图。 相反,它会多次绘制最后的情节。 我还没有想出为什么 – 它可能必须做的aesaes_stringggplot中调用。

否则,希望你能find有用的function。

使用dplyrtidyr

 x <- rnorm(100) eps <- rnorm(100,0,.2) df <- as.data.frame(cbind(x, eps)) %>% mutate(p1 = 3*x+eps, p2 = 2*x+eps) %>% tidyr::gather("plot", "value", 3:4) %>% ggplot(aes(x = x , y = value))+ geom_point()+geom_smooth()+facet_wrap(~plot, ncol =2) df 

cowplot你一个很好的方式来做到这一点,适合出版。

 x <- rnorm(100) eps <- rnorm(100,0,.2) A = qplot(x,3*x+eps, geom = c("point", "smooth"))+theme_gray() B = qplot(x,2*x+eps, geom = c("point", "smooth"))+theme_gray() cowplot::plot_grid(A, B, labels = c("A", "B"), align = "v") 

在这里输入图像描述