如何加快在 for 循环中添加许多 ggplot layers/geoms?

How can I speed up adding many ggplot layers/geoms in a for loop?

library(ggplot2)
library(magrittr)
library(data.table)

Nbars = 2

generate_eg_data <- function() {
  eg_data = data.table(LL = 0:99, UL = 1:100, val = sort(runif(100, 0, 1)))
  eg_data[, valColor := val %>% multiply_by(255) %>% ceiling %>% as.hexmode %>% list %>% c(., ., .) %>% do.call(paste0, .) %>% paste0("#", .)]
  return(eg_data)
}

lst_eg_data <- lapply(seq(Nbars), function(i) {
  return(generate_eg_data())
})

p <- ggplot() +
  scale_x_continuous(limits = c(0, 100)) +
  scale_y_continuous(limits = c(0, Nbars + 1)) +
  theme_classic()
for (i in seq(Nbars)) {
  for (j in seq(nrow(lst_eg_data[[i]]))) {
    p %<>% add(geom_ribbon(data = lst_eg_data[[i]][j, .(x = c(LL, UL), ymin = rep(i - 0.25, 2), ymax = rep(i + 0.25, 2))],
                           aes(x = x, ymin = ymin, ymax = ymax),
                           fill = lst_eg_data[[i]][j, valColor]))
  }
}
p

以上应该足以说明我想要的结果了。为简单起见,在上面我为每个条生成了类似的 valColor,但实际上每个条因不同的 RGB 组合(即不仅是灰度)而变化很大。

代码有效,但速度太慢,因为实际上我在每个图中有 6 个条形图和 36 个这样的图以及一些其他辅助层,我想将它们一起放在一个图中gridExtra::arrangeGrob 的帮助。这个过程已经 运行 一个多小时了,还没有完成。

我想知道这是否是因为我试图使用 100 个单独的层添加每个条。如果是这样,是否可以将每个条形图添加为单个图层,同时保留为每个条形图定义的独特着色方案?或者还有其他原因导致绘图缓慢,我怎样才能让它更有效率?谢谢!

循环使整个事情变慢,没有必要,不好的风格,应该避免。 相反,外循环 (i) 应该与 y 美学相匹配,而内循环 (j) 应该与 x 美学相匹配。 (除此之外,人们通常会使用 p <- p + geom_ribbon() 而不是 %<>%。)

这是一种使用 geom_tile() 的方法,但其他 geom 也可能适用。 请注意,我首先将您的两个数据帧列表 (lst_eg_data) 转换为一个数据帧。

df1 <- melt(lst_eg_data, id.vars = names(lst_eg_data[[1]]))

ggplot(df1, aes(x = LL, y = L1, fill = valColor, height = .5)) +
    scale_fill_grey() +
    geom_tile(show.legend = FALSE)