【问题标题】:Multiple ggplot2 graphs with shared Data具有共享数据的多个 ggplot2 图
【发布时间】:2023-03-15 05:29:01
【问题描述】:

如何在回收数据时制作多个相同数据但因不同因素(列)而不同颜色的图?这是gridExtracowplot 所做的不同吗?

目标: 我的目标是直观地比较有效聚类相同数据的不同结果。 我目前认为,直观地比较 2-4 种聚类算法的最简单方法是将它们彼此相邻绘制。

因此,如何将相同的数据并排绘制不同的颜色?

挑战/规范:性能非常重要。我要制作大约 30,000 张图表,每张图表有 450 - 480 分。数据被“回收”是至关重要的。

我可以使用包cowplotgridExtra 并排绘制它们。我今天才开始使用gridExtra,但它似乎可以回收数据,并且就我的目的而言比cowplot 更好。 更新: u/eipi10 证明如果我在绘图前收集列,facet_wrap 可以工作。

设置

    #Packages
     library(ggplot2)
     library(cowplot)
     library(gridExtra)
     library(pryr) #memory profile

    #Data creation
      x.points  <- c(1, 1, 1, 3, 3, 3, 5, 5, 5)
      y.points  <- c(1, 3, 5, 1, 3, 5, 1, 3, 5)
      cl_vert   <- c("A", "A", "A", "B", "B", "B", "C", "C", "C")
      cl_hoz    <- c("A", "B", "C", "A", "B", "C", "A", "B", "C")
      cl_cent   <- c("A","A","A","A", "B", "A","A","A","A")
    df <- data.frame(x.points, y.points, cl_vert, cl_hoz, cl_cent)

绘制图表

    #Graph function and individual plots
     graph <- function(data = df, Title = "", color.by, legend.position = "none"){
       ggplot(data, aes(x = `x.points`, y = `y.points`)) +
         geom_point(aes(color = as.factor(color.by))) + scale_color_brewer(palette = "Set1") + 
         labs(subtitle = Title, x = "log(X)", y = "log(Y)", color = "Color" ) + 
         theme_bw() + theme(legend.position = legend.position)  
     }

     g1 <- graph(Title = "Vertical", color.by = cl_vert)
     g2 <- graph(Title = "Horizontal", color.by = cl_hoz)
     g3 <- graph(Title = "Center", color.by = cl_cent)

    #Cowplot
     legend <- get_legend(graph(color.by = cl_vert, legend.position = "right")) #Not a memory waste
     plot <- plot_grid(g1, g2, g3, labels = c("A", "B", "C"))
     title <- ggdraw() + draw_label(paste0("Data Ex ", "1"), fontface = 'bold') 
     plot2 <- plot_grid(title, plot, ncol=1, rel_heights=c(0.1, 1)) # rel_heights values control title margins
     plot3 <- plot_grid(plot2, legend, rel_widths = c(1, 0.3))
     plot3

    #gridExtra
     plot_grid.ex <- grid.arrange(g1, g2, g3, ncol = 2, top = paste0("Data Ex ", "1"))
     plot_grid.ex

pryr 的内存使用情况

    #Comparison
     object_size(plot_grid) #315 kB 
     object_size(plot3) #1.45 MB
    #Individual objects
     object_size(g1) #756 kB
     object_size(g2) #756 kB
     object_size(g3) #756 kB
     object_size(g1, g2, g3) #888 kB
     object_size(legend) #43.6 kB

其他问题: 写完这个问题并提供了样本数据,我才想起gridExtra,试了一下,似乎比它的组件图的组合数据占用内存少。我认为 g1、g2 和 g3 共享相同的数据,但着色分配除外,这就是为什么各个组件与总对象大小之间存在大约 130 kB 差异的原因。为什么 plot_grid 占用的空间比这还少? ls.str(plot_grid) 似乎没有显示 g1、g2 和 g3 的任何合并。我最好的选择是使用lineprof() 并逐行比较吗?

我浏览/阅读/咨询过的来源:

请多多包涵,因为我是一名新程序员(12 月才真正开始编写脚本);我还不了解所有技术细节,但我想了解。

【问题讨论】:

  • 你打算如何查看 30,000 个地块?也许有更好的方法来做你想做的事?
  • 我不会一次处理所有 30,000 组数据。我也不打算保存图表本身,而是保存用于制作它们的数据。实际上,我将相同格式的数据分布在约 500 个文件夹中(按簇数和 HDBSCAN 给出的 p_value 分类)。我一次加载一个 csv 文件。那个 csv 可以有 2 组数据到 200。我使用 tidyverse group_by()nest() 来形成一个嵌套列表,然后运行 ​​lapply 来制作所有的图表。然后我一次调用一个图表(我有一个闪亮的应用程序来导航目录并显示正确的图表)

标签: r performance memory ggplot2 gridextra


【解决方案1】:

如果您将数据转换为长格式,则分面将在这里起作用。这是一个例子:

library(tidyverse)

df %>% gather(method, cluster, cl_vert:cl_cent) %>% 
  ggplot(aes(x = x.points, y = y.points)) + 
    geom_point(aes(color = cluster)) + 
    scale_color_brewer(palette = "Set1") + 
    theme_bw() +
    facet_wrap(~ method)

【讨论】:

  • 其实没想过把数据转成长格式!这是一个潜在的解决方案。
  • ggplot2 faceting 和美学设计用于最有效地处理长格式数据。
  • 这比cowplot快很多。太感谢了!我将 gridExtra 与上述 facet 方法进行了比较,速度快了 54.593 倍。
  • gridExtra::grid.arrangecowplot::plot_grid 主要用于在单个“画布”上一起布置单独的图,而不是替代刻面(当刻面有意义时)。
【解决方案2】:

如果您想提高性能,请不要使用任何这些软件包,包括 ggplot2。 gridExtra、cowplot 和其他人总是会让事情变得更慢,而且它们不会在任何意义上“回收”数据(不清楚你的意思)。

我建议在 ggplot2 之外进行所有耗时的数据处理,并绘制已经更接近最终映射的结果(即已经分配了颜色组等)。您可能会发现 ggplot2 对您的应用程序来说变得过分且缓慢(晶格通常更快,基础图也是如此)。

如果你真的想要共享数据,我认为像 d3.js 这样的东西可能会让你最接近这个目标,尽管它只会让浏览器在渲染时进行数据复制。一旦数据点呈现在屏幕上,它们就必须是独立的和重复的,所以问题是在管道中的哪个位置最方便和高效。

【讨论】:

  • 我对提高性能很感兴趣。我将研究格子图和基图。在运行绘图之前如何分配颜色组?我担心的一个问题是,我实际上通过附加列(基于图表外的条件)自定义了一些点的形状/大小,所以我担心将所有这些转换回晶格/基数。我认为回收数据是当 R 再次引用同一个对象以节省内存时。例如:x
  • 既然您提到您对编程比较陌生,我强烈建议您不要太担心对象大小和性能(在一定程度上)。 R 对于交互式分析非常有用,当手头的问题比平常更大时,您的第一个策略应该是蛮力增加计算机资源:仅使用 ggplot2 生成这些图需要多长时间?过夜?周末?租一台 HPC 机器?无论完成什么工作都比试图绕过你正在学习的整个生态系统要好。
  • 感谢您的洞察力;我确实认为计算机资源的增加会解决所有问题。 eipi10 的回答在我的工作计算机上加快了速度,几乎可以接受。我知道 R 适合交互式分析,但我需要加快一些分析。我以前可以在工作中使用网格计算,但服务器崩溃了,不再支持我需要的工具。由于工作情况复杂,我无法升级我的硬件。如果我不能改进这些结果,那么我的主管希望我使用低效的程序手动对这 30k 个图进行聚类...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
相关资源
最近更新 更多