我想使用ggplot2包并排放置两个图,即执行par(mfrow=c(1,2))的等效操作。

例如,我想让下面两个图以相同的比例并排显示。

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

我需要把它们放到同一个数据帧里吗?

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

当前回答

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

其他回答

您可以使用温斯顿张的R食谱下面的多绘图函数

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

}

使用重塑包可以完成如下操作。

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)

使用补丁包,你可以简单地使用+运算符:

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))


p1 + p2

其他操作符包括/,用于堆叠图,并排放置图,以及(),用于对元素进行分组。例如,你可以用(p1 | p2 | p3) /p来配置上面一行的3个地块和下面一行的一个地块。有关更多示例,请参阅包文档。

还有一个多面板图形包是值得一提的。看看这个答案。

library(ggplot2)
theme_set(theme_bw())

q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
q4 <- ggplot(mtcars) + geom_bar(aes(carb))

library(magrittr)
library(multipanelfigure)
figure1 <- multi_panel_figure(columns = 2, rows = 2, panel_label_type = "none")
# show the layout
figure1

figure1 %<>%
  fill_panel(q1, column = 1, row = 1) %<>%
  fill_panel(q2, column = 2, row = 1) %<>%
  fill_panel(q3, column = 1, row = 2) %<>%
  fill_panel(q4, column = 2, row = 2)
figure1

# complex layout
figure2 <- multi_panel_figure(columns = 3, rows = 3, panel_label_type = "upper-roman")
figure2

figure2 %<>%
  fill_panel(q1, column = 1:2, row = 1) %<>%
  fill_panel(q2, column = 3, row = 1) %<>%
  fill_panel(q3, column = 1, row = 2) %<>%
  fill_panel(q4, column = 2:3, row = 2:3)
figure2

由reprex包(v0.2.0.9000)于2018-07-06创建。

如果您希望使用循环绘制多个ggplot图(例如:使用循环在ggplot中创建具有不同y轴值的多个图),上述解决方案可能不太有效,这是分析未知(或大型)数据集的理想步骤(例如,当您希望绘制数据集中所有变量的计数时)。

下面的代码展示了如何使用上面提到的“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打印的所有变量的Counts

dt = ggplot2::diamonds
plotAllCounts(dt)

需要注意的一点是: 在上面的代码中使用aes(get(strX)),而不是aes_string(strX)将不会绘制所需的图形,这是在处理ggplot时通常在循环中使用的。相反,它会多次绘制最后一个图形。我还没有弄清楚为什么-它可能必须做aes和aes_string在ggplot中被调用。

除此之外,希望你会发现这个函数有用。