简体   繁体   English

如何在一个绘图列表中组合两个绘图列表(由 ggplot 图组成)?

[英]How to combine two plot lists (made of ggplot graphs) in a single plot list?

I have two plot lists, each one with 3 graphs, made with ggplot:我有两个绘图列表,每个都有 3 个图表,用 ggplot 制作:

plot_list1:情节列表1: 在此处输入图像描述

plot_list2: plot_list2: 在此处输入图像描述

I would like to combine them in a single list, where all graphs are present, as this one:我想将它们组合在一个列表中,其中所有图表都存在,如下所示:

在此处输入图像描述

I have thought to create plot_list1 as you see above, and plot_list2 with transparent background, as follows:如上所示,我想创建 plot_list1 和透明背景的 plot_list2 ,如下所示: 在此处输入图像描述

and add them in this way:并以这种方式添加它们:

for(i in 1:3)
{
plot_list[[i]] <- plot_list1[[i]] + plot_list2[[i]]  
}

But it gives me the error message: Error in ggplot_add() : !但它给了我错误信息: ggplot_add()中的错误:! Can't add plot_list2[[i]] to a ggplot object.无法将plot_list2[[i]]添加到 ggplot 对象。

How could I do?我该怎么办?

Hereafter my complete code:此后我的完整代码:

double_plot <- function()

{
x1 <- c(1, 2, 3, 4, 5)
y1 <- c(10, 20, 30, 40, 50)
x2 <- c(2, 4, 6, 8, 10)
y2 <- c(15, 20, 25, 30, 35)
x3 <- c(1, 2, 3, 4, 5)
y3 <- c(20, 40, 60, 80, 100)

x4 <- c(1, 2, 3, 4, 5)
y4 <- c(13, 23, 33, 43, 53)
x5 <- c(2, 4, 6, 8, 10)
y5 <- c(15, 35, 55, 75, 95)
x6 <- c(1, 2, 3, 4, 5)
y6 <- c(35, 40, 45, 50, 55)

df1 <- data.frame(x1, y1, x2, y2, x3, y3)
df2 <- data.frame(x4, y4, x5, y5, x6, y6)

n <- ncol(df1)
m <- nrow(df1)

plot_list1 <- list()
plot_list2 <- list()

for(i in 1:(n/2))
{
  p <- i+(i-1)
  
  datax <- df1[,p]
  datay <- df1[,p+1]
  
  data <- cbind(datax, datay)
  data_df <- as.data.frame(data)

  plot_list1[[i]] <- ggplot(data_df, aes(x=datax, y=datay)) +
    geom_point(size = 4) +
    geom_line(color="red", size = 2) +
    xlim(0, 10) +
    ylim(0, 100)    
}


for(i in 1:(n/2))
{
  p <- i+(i-1)

  datax <- df2[,p]
  datay <- df2[,p+1]
  
  data <- cbind(datax, datay)
  data_df <- as.data.frame(data)
  
  plot_list2[[i]] <- ggplot(data_df, aes(x=datax, y=datay)) +
    geom_point(size =4) +
    geom_line(color="blue", size =2) +
    theme(
      panel.background = element_rect(fill = "transparent",colour = NA), 
      panel.grid.minor = element_blank(), 
      panel.grid.major = element_blank()) +
    xlim(0, 10) +
    ylim(0, 100)   
}

for(i in 1:(n/2))
{
 plot_list[[i]] <- plot_list1[[i]] + plot_list2[[i]]  # if you comment this line and modify (in the next one) arrangeGrob(grobs=plot_list... in arrangeGrob(grobs=plot_list1 or grobs=plot_list2, you will obtain the two different plot lists.
}

ggsave(width = 30, height = 10, dpi = 300, file = "test.pdf", arrangeGrob(grobs=plot_list, ncol = 3))

dev.off() 
}

If you want your lines from both datasets in one plot I would suggest to simply use one call to ggplot instead of trying to somehow overlay one by the other.如果您希望将两个数据集中的线条都放在一个图中,我建议您简单地使用一次调用 ggplot 而不是尝试以某种方式一个接一个地叠加。 To this end use the same names for both dataframes and bind them together using eg dpylr::bind_rows .为此,对两个数据帧使用相同的名称,并使用例如dpylr::bind_rows将它们绑定在一起。 Also, instead of looping over columns I would suggest to convert your data to long format using eg tidyr::pivot_longer .此外,我建议不要循环列,而是使用例如tidyr::pivot_longer将您的数据转换为长格式。 After doing you could easily loop over your data using lapply to create your plots:完成后,您可以使用lapply轻松循环数据以创建绘图:

library(dplyr)
library(ggplot2)
library(tidyr)

names(df2) <- names(df1)

df <- list(df1, df2) |>
  bind_rows(.id = "df_id") |>
  pivot_longer(-df_id, names_to = c(".value", "id"), names_pattern = "^(x|y)(.*)$")

plot_fun <- function(.data) {
  ggplot(.data, aes(x = x, y = y)) +
    geom_point(size = 4) +
    geom_line(aes(color = df_id), size = 2) +
    scale_color_manual(values = c("red", "blue")) +
    xlim(0, 10) +
    ylim(0, 100)
}

split(df, df$id) |>
  lapply(plot_fun) |>
  gridExtra::grid.arrange(grobs = _, ncol = 3)

A second and my personally preferred option would be to simply use faceting:第二个也是我个人更喜欢的选择是简单地使用刻面:

plot_fun(df) + facet_wrap(~id)

在此处输入图像描述

Your current code adds ggplot() +... + ggplot() +.... .您当前的代码添加ggplot() +... + ggplot() +....

There should really only be one ggplot call.实际上应该只有一个 ggplot 调用。 Then you add other lines of code to that ggplot call.然后将其他代码行添加到该 ggplot 调用中。

You can fix this by removing the ggplot() call in the second loop您可以通过删除第二个循环中的ggplot()调用来解决此问题

Your code then looks something likes this:然后您的代码看起来像这样:

  for(i in 1:(n/2))
  {
    p <- i+(i-1)
    
    datax <- df1[,p]
    datay <- df1[,p+1]
    
    data <- cbind(datax, datay)
    data_df <- as.data.frame(data)
    
    plot_list1[[i]] <- ggplot(data_df, aes(x=datax, y=datay)) +
      geom_point(size = 4) +
      geom_line(color="red", size = 2)   
  }
  
  
  for(i in 1:(n/2))
  {
    p <- i+(i-1)
    
    datax <- df2[,p]
    datay <- df2[,p+1]
    
    data <- cbind(datax, datay)
    data_df <- as.data.frame(data)
    
    plot_list2[[i]] <- plot_list1[[i]] + geom_point(data = data_df, aes(x=datax, y=datay), size =4) +
      geom_line( data = data_df, aes(x=datax, y=datay), color = "blue", size =2)+
      theme(
        panel.background = element_rect(fill = "transparent",colour = NA), 
        panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank()) +
      xlim(0, 10) +
      ylim(0, 100)
  }  
  
  plot_list <- list()
  
  for(i in 1:(n/2))
  {
    plot_list[[i]] <- plot_list2[[i]]  # if you comment this line and modify (in the next one) arrangeGrob(grobs=plot_list... in arrangeGrob(grobs=plot_list1 or grobs=plot_list2, you will obtain the two different plot lists.
  }

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM