如何加快在 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)
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)