我想使用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()

当前回答

更新:这个答案非常古老。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
  }
 }
}

其他回答

是的,我认为你需要适当地安排你的数据。一种方法是:

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或重塑中有更好的技巧——我仍然没有真正跟上速度 哈德利设计的这些强大的软件包。

如果您希望使用循环绘制多个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中被调用。

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

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

根据我的经验,网格。如果您试图在循环中生成情节,那么Arrange工作得很好。

简短代码片段:

gridExtra::grid.arrange(plot1, plot2, ncol = 2)

**更新此注释以展示如何在for循环中使用grid.arrange()为类别变量的不同因素生成图表。

for (bin_i in levels(athlete_clean$BMI_cat)) {

plot_BMI <- athlete_clean %>% filter(BMI_cat == bin_i) %>% group_by(BMI_cat,Team) %>% summarize(count_BMI_team = n()) %>% 
          mutate(percentage_cbmiT = round(count_BMI_team/sum(count_BMI_team) * 100,2)) %>% 
          arrange(-count_BMI_team) %>% top_n(10,count_BMI_team) %>% 
          ggplot(aes(x = reorder(Team,count_BMI_team), y = count_BMI_team, fill = Team)) +
            geom_bar(stat = "identity") +
            theme_bw() +
            # facet_wrap(~Medal) +
            labs(title = paste("Top 10 Participating Teams with \n",bin_i," BMI",sep=""), y = "Number of Athletes", 
                 x = paste("Teams - ",bin_i," BMI Category", sep="")) +
            geom_text(aes(label = paste(percentage_cbmiT,"%",sep = "")), 
                      size = 3, check_overlap = T,  position = position_stack(vjust = 0.7) ) +
            theme(axis.text.x = element_text(angle = 00, vjust = 0.5), plot.title = element_text(hjust = 0.5), legend.position = "none") +
            coord_flip()

plot_BMI_Medal <- athlete_clean %>% 
          filter(!is.na(Medal), BMI_cat == bin_i) %>% 
          group_by(BMI_cat,Team) %>% 
          summarize(count_BMI_team = n()) %>% 
          mutate(percentage_cbmiT = round(count_BMI_team/sum(count_BMI_team) * 100,2)) %>% 
          arrange(-count_BMI_team) %>% top_n(10,count_BMI_team) %>% 
          ggplot(aes(x = reorder(Team,count_BMI_team), y = count_BMI_team, fill = Team)) +
            geom_bar(stat = "identity") +
            theme_bw() +
            # facet_wrap(~Medal) +
            labs(title = paste("Top 10 Winning Teams with \n",bin_i," BMI",sep=""), y = "Number of Athletes", 
                 x = paste("Teams - ",bin_i," BMI Category", sep="")) +
            geom_text(aes(label = paste(percentage_cbmiT,"%",sep = "")), 
                      size = 3, check_overlap = T,  position = position_stack(vjust = 0.7) ) +
            theme(axis.text.x = element_text(angle = 00, vjust = 0.5), plot.title = element_text(hjust = 0.5), legend.position = "none") +
            coord_flip()

gridExtra::grid.arrange(plot_BMI, plot_BMI_Medal, ncol = 2)

}

下面包含了上面for循环中的一个样例图。 上述循环将为BMI类别的所有级别生成多个图。

样本图像

如果您希望在for循环中看到grid.arrange()的更全面的使用,请访问https://rpubs.com/Mayank7j_2020/olympic_data_2000_2016

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

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)