ggplot2: Die vier fortgeschrittenen Schichten

Wer mit ggplot2 ansprechende Grafiken erstellen will, findet mit den vier fortgeschrittenen Schichten flexible Möglichkeiten dafür.

ggplot2 und die Grammatik der grafischen Darstellung

Nachdem es gestern um ein simples Beispiel mit den drei Basisschichten Daten, Ästhetiken und Geometrien ging, widmen wir uns heute den vier fortgeschrittenen Schichten: Facetten (Facets), Statistische Transformationen, Koordinatensysteme, Themes.

Ausgangspunkt: Ein einfaches Streudiagramm

Wir beginnen mit einem simplen Streudiagramm. Es geht wieder um die Diamanten-Daten aus dem ggplot2-Paket.

library(tidyverse)

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(size = 0.5, alpha = 0.5) +
  labs(title = "Diamonds: Price by Carat (weight)",
       x = "Carat", y = "Price",
       caption = "Diamonds dataset, ggplot2")
ggplot2: Streudiagramm (scatterplot) der diamonds-Daten, mit Transparenz (alpha) und reduzierter Punktgröße

Eine Herausforderung bei diesen Daten besteht in ihrer schieren Menge: es geht um über 50.000 Datenpunkte. Da kommt es leicht zu Overplotting, d. h. sich überlappende Datenpunkte. Dem wird hier mit zwei Einstellung in der Geometrie (geom_point) abgeholfen: reduzierter Punktgröße (size) sowie einer gewissen Transparenz (alpha). Dank letzterer kann man hellere und dunklere Regionen im Diagramm unterscheiden.

Sowohl der Preis als auch die Karat-Zahl sind offenbar stark rechtsschief verteilt.

4. Schicht: Facetten (facets)

Die vierte Schicht in der Grammatik der grafischen Darstellung sind die sog. Facetten (facets). Ich sehe sie als besondere Stärke von ggplot2: So kann man leicht separate Diagramme für Untergruppen erstellen, die in einer Bilddatei abgelegt werden, sodass man nicht in externer Software (etwa Word oder Powerpoint) die Anordnung der Diagramme kontrollieren muss.

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(size = 0.5, alpha = 0.5) +
  facet_wrap(vars(cut)) +    # Alternativ: facet_wrap(~ cut)
  labs(title = "Diamonds: Price by carat (weight)",
       x = "Carat", y = "Price",
       caption = "Diamonds dataset, ggplot2")

Eine Codezeile genügt, um die Untergruppen zu definieren: facet_wrap(vars(cut)). Alternative Schreibweise: Formel-Interface mit der Tilde: facet_wrap(~ cut).

ggplot2: Diagramm mit Facetten (facets) für Untergruppen

Untergruppen können auch für Kombinationen mehrerer Variablen erstellt werden:

  • Mit facet_wrap() werden die Gruppen wie ein Band gewickelt; man kann die Anzahl der Zeilen oder Spalten fürs Layout vorgeben
  • Mit facet_grid() ensteht ein echtes zweidimensionales Raster, mit einer Zeilen- und einer Spaltenvariable für die Untergruppen.

5. Schicht: Statistische Transformationen

Die fünfte Schicht der Grammatik der grafischen Darstellung umfasst statistische Transformationen. Hier fügen wir eine Trendgerade ins Diagramm ein:

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(size = 0.5, alpha = 0.5) +
  geom_smooth(method = "lm") +
  labs(title = "Diamonds: Price by Carat (weight)",
       subtitle = "Smoothing Method: lm",
       x = "Carat", y = "Price",
       caption = "Diamonds dataset, ggplot2")
ggplot2: Streudiagramm mit Trendgerade (geom_smooth)

Statistische Transformationen können auch mit stat_…()-Funktionen berechnet werden. Ein Beispiel ist stat_summary(), um etwa in Boxplots zusätzlich zum Median auch den Mittelwert anzuzeigen.

Eine Alternative zur Trendgeraden stellt eine nichtlineare Anpassungskurve dar, hier mittels GAM = Generalized Additive Model (Generalisiertes Additives Modell).

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(size = 0.5, alpha = 0.5) +
  geom_smooth(method = "gam") +
  labs(title = "Diamonds: Price by Carat (weight)",
       subtitle = "Smoothing Method: gam",
       x = "Carat", y = "Price",
       caption = "Diamonds dataset, ggplot2")
ggplot2-Diagramm mit nichtlinearer Anpassungskurve; hier: gam = generalized additive model

Die Steigung flacht im höheren Karat-Bereich deutlich ab, bei allerdings geringerer Datenbasis.

6. Schicht: Koordinatensysteme

Die sechste Schicht der Grammatik der grafischen Darstellung umfasst Anpassungen an den Koordinatensystemen. Hier stellen wir die x- und y-Achse auf logarithmische Skalen um und passen die y-Achsen-Beschriftungen auf US-Dollar an, jeweils ohne die zugrundeliegenden Daten zu verändern.

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(size = 0.5, alpha = 0.5) +
  geom_smooth(method = "gam") +
  scale_x_log10() +
  scale_y_log10(labels = scales::dollar) +
  labs(title = "Diamonds: Price by Carat (weight)",
       subtitle = "Axes on Base 10 Log Scale\nSmoothing Method: gam",
       x = "Carat", y = "Price",
       caption = "Diamonds dataset, ggplot2")

Skalen-bezogene Funktionen beginnen mit dem Präfix scale_, was ähnlich wie bei geom_xxx() die Suche im Kontextmenü von RStudio ermöglicht.

ggplot2-Diagramm mit logarithmischen Skalen sowie einer Achsenbeschriftung in US-Dollar per scale_x- und scale_y-Funktionen

Angesichts der bereits erwähnten rechtsschiefen Verteilungen sowohl bei Carat als auch Price wirken sich die logarithmischen Skalen positiv aus. Die Anpassungskurve steigt nun über den größten Teil des Wertebereichs nahezu linear an und flacht erst im letzten Teil (bei geringer Datenbasis) ab.

Wer mehr Flexibilität bei Skalentransformationen benötigt, kann sich mit folgenden Funktionen behelfen:

  • scale_x_continuous(trans = …)
  • scales::trans_new(), um eigene Transformationen zu definieren

7. Schicht: Themes

Die siebte Schicht der Grammatik der grafischen Darstellungen versetzt uns schließlich in die Lage, diverse Stil-Anpassungen vorzunehmen. Hier geht es um „Tinte, die keine Daten darstellt“ (auf Englisch etwas eleganter und knapper non-data ink).

Wenn wir das Diagramm nicht direkt ausgeben, sondern einem Objekt zuweisen, etwa durch p <- ggplot(…), können wir verschiedene Themes mit wenig Aufwand ausprobieren:

p + theme_classic()
ggplot2-Diagramm im theme_classic()-Stil
p + theme_dark()
ggplot2-Diagramm im theme_dark()-Stil

Neben den Themes, die in ggplot2 implementiert sind, gibt es eine Reihe weiterer Themes über Zusatzpakete wie ggthemes.

library(ggthemes)
p + theme_wsj()
ggplot2-Diagramm im Stil des Wall Street Journal: ggthemes::theme_wsj()

So genügt ein simpler Funktionsaufruf, um das Diagramm im Stil des Wall Street Journal darzustellen.

Selbstverständlich ist es auch möglich, eigene Theme-Anpassungen vorzunehmen:

p + theme(
  panel.background = element_blank(),
  panel.grid = element_blank(),
  axis.text = element_text(colour = "darkblue"))
ggplot2-Diagramm mit benutzerdefinierten theme-Anpassungen

Ausgehend vom Standard theme_gray() wurden hier der Hintergrund (panel.background) sowie die Rasterlinien (panel.grid) entfernt mittels element_blank(), um dann die Farbe der Achsenbeschriftungen auf blau umzustellen.

Ich hoffe, dieser schnelle Einstieg zeigt einige der zahlreichen Möglichkeiten, Diagramme anzupassen. Für weitere Ideen siehe z. B. den Beitrag Wie man Boxplots in R informativer gestaltet (ggplot2 und mehr) oder Beiträge unter dem Stichwort plotly.

Viel Erfolg mit Euren Datenvisualisierungen!

Die aktuelle Version des ggplot2-Buchs von Hadley gibt es kostenlos online zu lesen.

3 Gedanken zu „ggplot2: Die vier fortgeschrittenen Schichten“

Freue mich über Kommentare!