【问题标题】:Putting multiple ggplots generated by a for loop into one image [closed]将 for 循环生成的多个 ggplots 放入一个图像中[关闭]
【发布时间】:2020-02-08 11:43:20
【问题描述】:

第一次提问所以如果我错过了任何重要的细节,请提前道歉。我还是 R 的新手,但随着我了解更多,我会尝试为自己做出贡献。同时希望有人可以提供帮助。

我有一个 for 循环,可以从我的数据中生成多个图。情节本身是完美的,但我正在努力将情节 1 到 4 添加到单个图像中。

如果我使用plot(),我可以使用par(mfrow - c(1,2,3,4),但由于我要向每个绘图添加多个数据框,即在ggplot 中添加多个geom_point(),我认为我不能这样做。

我的数据看起来像这样,但要长得多,N01、N02 等线的多个数据点,我正在生成一个新图,其中包含 N01、N02 等的数据,叠加了 WT1 和 WT2 点。

我想我可能需要将循环的每次迭代保存到新变量中,然后使用multiplot() 来获得我想要的结果。

如果我想出答案,我会发布,但如果有人击败我,请提前感谢您。

N01 N01.01  0.0 7693
2   N01 N01.02  2.0 3404
3   N01 N01.03  2.0 3404
4   N01 N01.04  1.0 6395
5   N01 N01.05  1.0 5171
6   N01 N01.06  2.0 6001
7   N01 N01.07  1.0 6671
8   N01 N01.08  1.5 6700
9   N01 N01.09  1.0 9060
10  N04 N04.01  2.0 6857
11  N04 N04.02  4.0 10378

setwd ("C:/Users/HP/Desktop/Studio R/Patty")
df <- read.csv("Data/Raw V2.csv")

#need to create a new data frame with a new coluum taking information from another column
df2 <- split(df, df$ï..ID)
x1 <- df2$WT1[,3:4] #new var for the wild type that wants plotting on all the charts
x2 <- df2$WT6[,3:4]

plot_list <- list() #creates an empty list to save the plots in


for (i in 1:length(df2)){
  z1 <- df2[[i]][,3:4]#new var from the data fram i amount of times using data from column 3 to 4
  title <- (df2[[i]][,1][1]) #used later on to add the title variable in the legend
  par(mar=c(4,4,1,1), mfrow=c(2,2))
  f <- 
    ggplot(data=z1, aes(x=copies, y=leaf_area)) + 
    geom_point(aes(col="black"))+ #creates the plots of i
    geom_point(data=x1, aes(col="blue"))+  #adds the wt to all plots, aes neeeded to create legend
    geom_point(data=x2, aes(col="red"))+
    theme(panel.background = element_blank(), axis.line = element_line(colour = "black"),
          panel.grid.minor = element_line())+
    scale_color_identity(name = "", breaks = c("black", "blue", "red"), labels = c(paste0("(",title,")"),("(WT1)"),("(WT6)")), guide = "legend")+
    theme(legend.position = c(0.95, 0.95), legend.justification = c("right", "top"), legend.direction = "horizontal")+
    scale_x_continuous(limits = c(0, 4)) + #standarsises the axis
    scale_y_continuous(limits = c(0, 12000)) +
    xlab(bquote("Number of Inserts"))+
    ylab(bquote("Leaf Area (mm'^2')"))+
    ggtitle(df2[[i]][,1][1])
    plot_list[[i]] <- f
    list2env(plot_list[[i]], envir = globalenv()) #send the list to the global environment
}

在理想的世界中,这会起作用:

for (i in plot_list){
  par(mfrow = c(2,2))
  plot(i)
}

【问题讨论】:

  • 看看patchwork 包。此外,您能否使您的问题可重现和使用,例如iris 数据?
  • See here 获取有关如何提出可重复问题的提示!你可以帮助别人来帮助你!
  • 考虑是否可以使用 facet_wrap 会比制作多个绘图更好(通常是)

标签: r for-loop ggplot2 plot


【解决方案1】:

您尝试使用par(mfrow=...),这仅适用于基础 R 图。对于ggplot,如果你喜欢类似的东西,也许可以使用 gridExtra,因为你已经有了一个情节列表。您可以在下面使用iris 看到一个示例

同样作为评论,您很可能不需要使用list2env,因为您已经分配了它

library(ggplot2)
library(gridExtra)

plot_list <- list() 
df <- split(iris,iris$Species)

for(i in seq_along(df)){
plot_list[[i]] <- ggplot(df[[i]],aes(x=Sepal.Length,y=Sepal.Width))+
geom_point()+
ggtitle(names(df)[i])
}

grid.arrange(grobs=plot_list,ncol=2)

我知道你总是想比较一个参考。我将模拟一些看起来像你的数据的东西:

set.seed(100)
WT1 <- data.frame(Sepal.Length=seq(4,6.5,length.out=50),
Sepal.Width=seq(1.5,3,length.out=50)+rnorm(50,0.5,0.2),Species="WT1")
WT2 <- data.frame(Sepal.Length=seq(6,8,length.out=50),
Sepal.Width=seq(2,4.5,length.out=50)+rnorm(50,0.5,0.2),Species="WT2")

df <- rbind(iris[,c("Sepal.Length","Sepal.Width","Species")],WT1,WT2)
colnames(df)[3] <- "ID"

现在我们开始绘制:

# separate the two datasets you want:
obs <- droplevels(subset(df,!ID %in% c("WT1","WT2")))
ref <- droplevels(subset(df,ID %in% c("WT1","WT2")))

plot_list <- list() 
for(i in unique(obs$ID)){

thisDF <- rbind(subset(obs,ID==i),ref)
g <- ggplot(thisDF,aes(x=Sepal.Length,y=Sepal.Width,col=ID))+
geom_point() + theme(legend.position = c(0.9,0.9), 
legend.justification = c("right", "top"), 
legend.direction = "horizontal")+ggtitle(i)
plot_list[[i]] <- g
}
grid.arrange(grobs=plot_list,ncol=2)

【讨论】:

    【解决方案2】:

    感谢@StupidWolf,这是一个巨大的帮助和一种更优雅的做事方式,非常感谢。

    我确实找到了一种解决方法,虽然它相当笨重,但可能对某人有用。

    首先我删除了:

    plot_list[[i]] &lt;- f

    list2env(plot_list[[i]], envir = globalenv())

    然后从循环内部 我在循环中添加了以下内容:

    nam &lt;- paste("A", i, sep ="")

    为循环的每次迭代输出 A1、A2、A3

    assign(nam, f)

    为每次迭代创建一个新变量(f 是循环的 ggplot 输出)

    在我添加的循环之外:

    figure1 &lt;- ggarrange(A1, A2, A3, A4, ncol = 2, nrow = 2)

    figure2 &lt;- ggarrange(A5, A6, A7, A8, ncol = 2, nrow = 2)

    ggarrange 允许您将多个绘图分配给单个窗口

    如果您有 20 多个输出,这可能会在另一个 for 循环中完成。

    再次向@StupiudWolf 大喊,以获得更好的代码。

    【讨论】:

      猜你喜欢
      • 2017-08-30
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 2018-09-04
      • 1970-01-01
      • 2014-11-19
      相关资源
      最近更新 更多