Diagramm-Erstellung mit ggplot2 beschleunigen: Das ragg-Paket

Diagramme zu erstellen und zu speichern kann viel Zeit in Anspruch nehmen, vor allem bei großen Datenmengen oder wenn sehr viele Diagramme automatisiert zu generieren sind. Wie kann man den Vorgang für Diagramme mit dem beliebten ggplot2-Paket beschleunigen?

Das ragg-Paket von Thomas Lin Pedersen

Das ragg-Paket von Thomas Lin Pedersen ist eine R-Implementierung der AGG (Anti-Grain Geometry)-Bibliothek. AGG ist freie Software (open source), stammt von Maxim Shemanarev und wurde in C++ programmiert.

Die Diagramm-Erstellung zu beschleunigen kann so einfach sein: Das ragg-device (Ausgabegerät) muss lediglich innerhalb des ggsave-Befehls angegeben werden!

Diagramm-Erstellung beschleunigen mit ragg

Die Daten stammen wie zuletzt von der Webseite tsort.info und können auch von meinem github-Profil heruntergeladen werden. 

Zunächst habe ich die Daten gefiltert und eine benutzerdefinierte Funktion erstellt, um nachher den Diagramm-Code nicht wiederholen zu müssen.

library(tidyverse)
library(ragg)
library(ggthemes)
library(tictoc)

music <- readRDS("musicdata.rds")

# Theme aus dem ggthemes-Paket
theme_set(theme_solarized(base_size = 14))

# Top 6 Künstler / Bands mit den meisten Songs / Alben
top6 <- music %>% 
   group_by(artist) %>% 
   count() %>% 
   arrange(desc(n)) %>% 
   head() %>% 
   pull(artist)

# Daten nach den Top 6 filtern
top6 <- music %>% 
   filter(artist %in% top6) %>% 
   mutate(artist = fct_infreq(artist))

# Plot-Funktion
my_plot <- function() {
   top6 %>% 
   ggplot(aes(x = year, y = score)) +
     geom_point(alpha = 0.6) +
     geom_smooth(method = "gam") +           
     facet_wrap(~ artist, scales = "free") +
     scale_y_log10() +                     
     theme(axis.text.x = element_text(angle = 90)) +
     labs(title = "Scores by Year",
          subtitle = "Top 6 Bands / Artists by # of Songs / Albums",
          caption = "NB: Ranges of x and y axes vary!",
          x = "Year", y = "Score")
 }

Es folgt ein Code-Beispiel für den Geschwindigkeits-Vergleich. Um den Zeitbedarf der beiden Varianten (ohne und mit ragg-Device) zu vergleichen, nutze ich diesmal das R-Paket tictoc. Im Gegensatz zu bench und microbenchmark, die ich an anderer Stelle zeigte, genügt mir in diesem Fall eine einzige Messung. Die Stoppuhr wird mit tic() gestartet und mit toc() angehalten.

Diagramm-Erstellung in der Voreinstellung – ohne weitere Angabe greift ggplot2 auf das cairo device zu:

tic()
invisible(my_plot())
ggsave("Images/Top6_ggplot-default.png", width = 7, height = 5)
toc()

2.14 sec elapsed

Hier wird das Diagramm „unsichtbar“ erstellt – das genügt, um es speichern zu können. Bei direkter Anzeige fand ich die Ergebnisse nicht vergleichbar, da cairo und ragg unterschiedliche Voreinstellungen nutzen, etwa was die Auflösung betrifft. Hier lege ich die Auflösung in ggsave() fest (Breite und Höhe in inch).

Zum Vergleich der Code, der das ragg device nutzt:

tic()
invisible(my_plot())
ggsave("Images/Top6_ggplot-ragg.png", width = 7, height = 5,
        device = agg_png())
toc()

0.83 sec elapsed

Bei wiederholter Ausführung können die Laufzeiten etwas schwanken – die ragg-Variante war bei mir durchgängig mindestens doppelt so schnell. Bei größeren Laufzeiten ein durchaus relevanter Unterschied!

Wie sind Eure Erfahrungen mit Datenvisualisierung in R?