我一直在考虑使用par()或layout()函数来组合ggplots。是否可以使用这些功能?
假设我想绘制散点图的ggplot和直方图的ggplot。我希望将这两个图组合在一起(不是在单个画面中)。它适用吗?
我在R中使用简单的绘图尝试了它,而没有使用ggplot函数。它确实有效。
以下是Quick-R的示例,链接:http://www.statmethods.net/advgraphs/layout.html
# 4 figures arranged in 2 rows and 2 columns
attach(mtcars)
par(mfrow=c(2,2))
plot(wt,mpg, main="Scatterplot of wt vs. mpg")
plot(wt,disp, main="Scatterplot of wt vs disp")
hist(wt, main="Histogram of wt")
boxplot(wt, main="Boxplot of wt")
# One figure in row 1 and two figures in row 2
attach(mtcars)
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
hist(wt)
hist(mpg)
hist(disp)
但是当我尝试使用ggplot并组合情节时,我没有得到输出。
答案 0 :(得分:32)
library(ggplot2)
library(grid)
vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y)
plot1 <- qplot(mtcars,x=wt,y=mpg,geom="point",main="Scatterplot of wt vs. mpg")
plot2 <- qplot(mtcars,x=wt,y=disp,geom="point",main="Scatterplot of wt vs disp")
plot3 <- qplot(wt,data=mtcars)
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot")
plot5 <- qplot(wt,data=mtcars)
plot6 <- qplot(mpg,data=mtcars)
plot7 <- qplot(disp,data=mtcars)
# 4 figures arranged in 2 rows and 2 columns
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(plot1, vp = vplayout(1, 1))
print(plot2, vp = vplayout(1, 2))
print(plot3, vp = vplayout(2, 1))
print(plot4, vp = vplayout(2, 2))
# One figure in row 1 and two figures in row 2
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(plot5, vp = vplayout(1, 1:2))
print(plot6, vp = vplayout(2, 1))
print(plot7, vp = vplayout(2, 2))
答案 1 :(得分:13)
我认为值得更多关注的一个实用工具是layOut
以前的wq
包(注意大写“O”)。它已从wq
包中删除,因此我将下面的代码重命名为lay_out
以匹配典型的ggplot样式。它就像base::layout
,因为这些图可以有不同的大小,以行和列的形式排列。 lay_out
的每个参数都是一个3元素的列表,由绘图,绘制它的行索引以及绘制它的列索引组成。
例如,使用@Paul McMurdie的情节,
lay_out(list(plot1, 1, 1),
list(plot2, 1, 2),
list(plot3, 2, 1),
list(plot4, 2, 2),
list(plot5, 3, 1:2),
list(plot6, 4, 1:2),
list(plot7, 1:2, 3))
lay_out = function(...) {
x <- list(...)
n <- max(sapply(x, function(x) max(x[[2]])))
p <- max(sapply(x, function(x) max(x[[3]])))
grid::pushViewport(grid::viewport(layout = grid::grid.layout(n, p)))
for (i in seq_len(length(x))) {
print(x[[i]][[1]], vp = grid::viewport(layout.pos.row = x[[i]][[2]],
layout.pos.col = x[[i]][[3]]))
}
}
(代码来自wq
包的先前版本,来自commit history on the unofficial Github CRAN mirror。)
答案 2 :(得分:7)
涉及grid.layout
的答案有效,我已经使用了它,我对它进行了投票。但是,我通常觉得这个解决方案太繁琐且容易出错,而且我怀疑大多数经常这样做的ggplot2爱好者都把它包含在一个函数中。我在之前的搜索中找到了几个这样的包装函数,但我当前的主力解决方案是grid addon package called gridExtra
。它有一些有用的参数,但默认的行/列设置通常是你想要的:
library("ggplot2")
# Generate list of arbitrary ggplots
plot1 <- qplot(data = mtcars, x=wt, y=mpg, geom="point",main="Scatterplot of wt vs. mpg")
plot2 <- qplot(data = mtcars, x=wt, y=disp, geom="point",main="Scatterplot of wt vs disp")
plot3 <- qplot(wt,data=mtcars)
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot")
plot5 <- qplot(wt,data=mtcars)
plot6 <- qplot(mpg,data=mtcars)
plot7 <- qplot(disp,data=mtcars)
# You might have produced myPlotList using instead lapply, mc.lapply, plyr::dlply, etc
myPlotList = list(plot1, plot2, plot3, plot4, plot5, plot6, plot7)
library("gridExtra")
do.call(grid.arrange, myPlotList)
注意实际的“将我的图组合成一个图形”代码是一行(在加载gridExtra之后)。您可能会争辩说将图表放入列表是一个额外的行,但实际上我可以使用
grid.arrange(plot1, plot2, plot3, plot4, plot5, plot6, plot7)
对于少量的ggplots,这可能是更好的选择。但是,对于n_plots > 4
,您将开始怨恨必须命名并输入所有内容。