使用 alpha 来减少 R 包 ggplot2 中的过度绘图时会出现显着的运行时膨胀

Ben*_*Boi 5 alpha runtime r ggplot2

我有一组中等规模的数据,正在尝试可视化nrow(df)=7810。为了减少过度绘制,我使用了alpha=.3. 这显着减慢了 R 生成数字所需的时间。这是我的规格,

OS Name Microsoft Windows 10 Home
Version 10.0.18362 Build 18362
Processor Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz, 3401 Mhz, 4 Core(s), 8 Logical Processor(s)
Installed Physical Memory (RAM) 32.0 GB
System Type x64-based PC
R version 3.6.1 (2019-07-05) -- "Action of the Toes"
ggplot2 version 3.2.1
Run Code Online (Sandbox Code Playgroud)

这是正在发生的事情的一个示例,

> p <-ggplot(df, aes(x=x))
> t1<-function(){p + geom_point(aes(y=y), shape=4, size=.5)}
> t2<-function(){p + geom_point(aes(y=y), shape=4, size=.5, alpha=.3)}

> system.time(print(t1()))
   user  system elapsed 
   0.14    0.37    0.53 

> system.time(print(t2()))
   user  system elapsed 
   0.25   29.69   30.04 
Run Code Online (Sandbox Code Playgroud)

有谁知道是什么导致这个脚本速度如此显着?

mps*_*amm 4

单独的 alpha 值并不是造成速度减慢的原因。alpha 值与形状相结合似乎会减慢速度。

当与 alpha 值一起使用时,复杂的矢量形状(例如由 渲染的“x”)shape = 4似乎会大大减慢渲染时间。如果您不致力于shape = 4,使用类似的东西shape = 16可以在使用所需的 alpha 值时加快速度。下面的例子:

library(dplyr)
library(ggplot2)
df <- tibble(x = rnorm(n = 7810),
             y = rnorm(n = 7810))

p1 <- function() {
  p <- ggplot(df) +
    geom_point(aes(x, y), shape=4, size=.5)
  print(p)
}

p2 <- function() {
  p <- ggplot(df) +
    geom_point(aes(x, y), shape=4, size=.5, alpha = 0.3)
  print(p)
}

p3 <- function() {
  p <- ggplot(df) +
    geom_point(aes(x, y), shape=16, size=.5, alpha = 0.3)
  print(p)
}

p4 <- function() {
  p <- ggplot(df) +
    geom_point(aes(x, y), shape=22, size=.5, alpha = 0.3)
  print(p)
}

test <- microbenchmark::microbenchmark(no_alpha = p1(),
                               alpha = p2(),
                               alpha_circle = p3(),
                               alpha_square = p4(),
                               times = 10)

print(test)
Run Code Online (Sandbox Code Playgroud)
Unit: milliseconds
         expr        min         lq       mean     median         uq       max neval
     no_alpha   837.5163   851.7994  1025.0569   910.3687  1173.8753  1403.087    10
        alpha 41456.3393 41708.0781 45831.6033 42589.4998 45219.8180 59578.347    10
 alpha_circle   429.7718   536.9076   719.5507   549.7952   555.9002  1780.282    10
 alpha_square   800.1380   806.5523   882.0163   815.6232   842.4669  1450.395    10
Run Code Online (Sandbox Code Playgroud)

编辑:

我们可以使用microbenchmarkpurrr来查看什么形状可以实现最快的绘图时间。

Unit: milliseconds
         expr        min         lq       mean     median         uq       max neval
     no_alpha   837.5163   851.7994  1025.0569   910.3687  1173.8753  1403.087    10
        alpha 41456.3393 41708.0781 45831.6033 42589.4998 45219.8180 59578.347    10
 alpha_circle   429.7718   536.9076   719.5507   549.7952   555.9002  1780.282    10
 alpha_square   800.1380   806.5523   882.0163   815.6232   842.4669  1450.395    10
Run Code Online (Sandbox Code Playgroud)

定时

看起来形状值 0、1 和 15 到 22 提供的渲染时间比其余值更快。

2021 年 2 月更新

我现在想更新这一点,您可以在 RStudio 中选择聚合图形设备。我注意到使用此选项可以提高质量和性能。下面包含使用 png、agg 和 cairo 图形设备的基准:

library(purrr)
library(microbenchmark)

df <- tibble(x = rnorm(n = 7810),
             y = rnorm(n = 7810))

s <- tibble(shape = c(0:24))

plot_fun <- function(shape) {
  p <- ggplot(df) +
    geom_point(aes(x, y), 
               shape = shape,
               alpha = 0.3)
  print(p)
}


test_fun <- function(shape) {
  microbenchmark(plot_fun(shape = shape),
                 times = 10)
}

s <- s %>%
  mutate(test = map(.$shape, 
                    ~test_fun(shape = .x)))

s %>% 
  tidyr::unnest(test) %>%
  mutate(time = microbenchmark:::convert_to_unit(time, "ms")) %>%
  ggplot() +
  geom_boxplot(aes(x = shape, y = time, group = shape), outlier.shape = NA) +
  scale_x_continuous(breaks = c(0:24)) +
  scale_y_log10() +
  coord_flip()
Run Code Online (Sandbox Code Playgroud)
Unit: milliseconds
  expr        min         lq       mean     median         uq        max neval
  ragg   143.6093   145.6143   147.0587   146.9873   149.2117   150.4617    10
   png 16156.0102 16490.5932 16525.7275 16518.1758 16548.8938 16963.1056    10
 cairo   176.1562   179.4485   181.5183   181.0518   183.5970   188.6689    10
Run Code Online (Sandbox Code Playgroud)

基准测试显示了使用 ragg 或 cairo 图形设备的一些重大改进。当使用“更简单”的符号系统时,没有任何实质性的改进。