我想使用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()
我想使用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()
当前回答
是的,我认为你需要适当地安排你的数据。一种方法是:
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或重塑中有更好的技巧——我仍然没有真正跟上速度 哈德利设计的这些强大的软件包。
其他回答
Ggplot2基于网格图形,网格图形提供了在页面上安排图形的不同系统。par(mfrow…)命令并没有直接的对等物,因为网格对象(称为grobs)不一定是立即绘制的,但在转换为图形输出之前,可以作为常规R对象存储和操作。这比现在绘制基础图形的模型具有更大的灵活性,但策略必然略有不同。
我编写grid.arrange()是为了提供一个尽可能接近par(mfrow)的简单接口。在其最简单的形式中,代码看起来像:
library(ggplot2)
x <- rnorm(100)
eps <- rnorm(100,0,.2)
p1 <- qplot(x,3*x+eps)
p2 <- qplot(x,2*x+eps)
library(gridExtra)
grid.arrange(p1, p2, ncol = 2)
在这个小插图中详细介绍了更多的选项。
一个常见的抱怨是,图不一定是对齐的,例如,当它们有不同大小的轴标签时,但这是通过设计:网格。Arrange没有尝试处理特殊情况下的ggplot2对象,并将它们与其他grobs(例如,晶格图)同等对待。它只是将抓取放在矩形布局中。
对于ggplot2对象的特殊情况,我编写了另一个函数ggarrange,该函数具有类似的接口,它尝试对齐绘图面板(包括分面图),并尝试尊重用户定义的纵横比。
library(egg)
ggarrange(p1, p2, ncol = 2)
这两个函数都与ggsave()兼容。对于不同选项的一般概述和一些历史背景,本小插图提供了额外的信息。
使用重塑包可以完成如下操作。
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)
还可以考虑ggpubr包中的ggarrange。它有很多好处,包括在情节之间对齐轴和将常见图例合并为一个图例的选项。
更新:这个答案非常古老。gridExtra::grid.arrange()现在是推荐的方法。 我把这个留在这里,也许有用。
Stephen Turner在Getting Genetics Done博客上发布了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
}
}
}
还有一个多面板图形包是值得一提的。看看这个答案。
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创建。