Menu

ggplot2 in R: ein Einsteigerleitfaden zur Grammatik der Grafiken

Wie ggplot2 funktioniert - das Denkmodell aus Daten + aes() + geom, Zuordnen vs. Setzen von Ästhetiken, labs(), facet_wrap(), Themes und Speichern mit ggsave().

ggplot2 baut Diagramme aus Schichten

ggplot2 ist R's meistgenutztes Grafikpaket, und der Grund, warum Leute darauf schwören, ist eine Designidee: die Grammatik der Grafiken. Base R gibt dir eine Funktion pro Diagramm - plot(), hist(), barplot() -, jede mit eigenen Argumenten. ggplot2 gibt dir stattdessen einen kleinen Satz kombinierbarer Bausteine - einen Datensatz, eine Zuordnung von Spalten zu visuellen Eigenschaften und Zeichenschichten -, die sich mit + zu jedem beliebigen Diagramm verbinden. Lerne die Grammatik einmal, und jeder neue Diagrammtyp ist derselbe Satz mit einem geänderten Wort. Als Bonus sehen die Voreinstellungen (graues Feld, sinnvolle Achsen, automatische Legenden) ohne jeden Gestaltungsaufwand vorzeigbar aus.

Es ist ein Zusatzpaket, braucht also eine einmalige Installation und ein Laden je Sitzung:

install.packages("ggplot2")   # once, on your machine
library(ggplot2)              # at the top of every script that uses it

Eine Erwartung vorab: ggplot2 will einen Data Frame (keine losen Vektoren), idealerweise im aufgeräumten langen Format - eine Zeile pro Beobachtung, eine Spalte pro Variable. Sind deine Daten breit, löst das Pivotieren ins Lange meist auf, was wie ein Zeichenproblem aussah.

Das Denkmodell: Daten, Zuordnung, Geometrie

Jedes ggplot beantwortet drei Fragen, eine pro Baustein:

  1. Daten - welcher Data Frame? ggplot(mtcars, ...)
  2. Zuordnung - welche Spalten steuern welche visuellen Eigenschaften? aes(x = wt, y = hp)
  3. Geometrie - wie sollen die Beobachtungen gezeichnet werden? + geom_point()

Hier die Anatomie, Token für Token:

ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point()
  • ggplot(mtcars, ...) beginnt ein Diagramm, dessen Standarddaten mtcars sind. Für sich allein zeichnet es ein leeres graues Feld - noch keine Schichten.
  • aes(x = wt, y = hp) ist die ästhetische Zuordnung: Die horizontale Position kommt aus der Spalte wt, die vertikale aus hp. Beachte, dass du nackte Spaltennamen schreibst, nicht mtcars$wt - die Zuordnung wird innerhalb der Daten ausgewertet, die du übergeben hast.
  • + geom_point() ergänzt eine Schicht, die jede Zeile als Punkt zeichnet. Das + ist wirklich eine Addition von Schichten: Das Diagramm ist ein Objekt, das du aufbaust, und du kannst weiter ergänzen - ein weiteres Geom, Beschriftungen, ein Theme - jeweils mit einem weiteren +.

Führ es aus, und du bekommst dieselbe Gewicht-vs-PS-Streuung wie die Base-R-Variante im Streudiagramm-Leitfaden, auf einem grauen Feld mit weißen Gitterlinien. Tausch geom_point() gegen geom_line(), und dieselbe Zuordnung wird zum Liniendiagramm - das ist die Grammatik bei der Arbeit.

Die Geoms, die du tatsächlich nutzen wirst

Ein Dutzend Geoms deckt fast die gesamte Alltagsarbeit ab:

geom_point()       # scatter plot: two numeric variables
geom_line()        # line chart: trends over an ordered variable
geom_col()         # bar chart from pre-computed heights (needs y)
geom_bar()         # bar chart that counts raw rows for you (no y)
geom_histogram()   # distribution of one numeric variable (set binwidth)
geom_boxplot()     # distributions compared across groups
geom_smooth()      # fitted trend line; method = "lm" for straight

Schichten stapeln sich, und genau da beginnt ggplot2, Base R an Ausdruckskraft zu schlagen: geom_point() + geom_smooth(method = "lm") ist ein Streudiagramm mit Regressionsgerade und Konfidenzband, in einer lesbaren Zeile. Weil Diagramme Objekte sind, kannst du auch eine Basis speichern und davon abzweigen:

p <- ggplot(mtcars, aes(x = wt, y = hp)) + geom_point()

p + geom_smooth(method = "lm")   # one variant
p + geom_smooth()                # another (loess curve)

Zuordnen vs. Setzen: die klassische aes()-Verwirrung

Der eine Fehler, den jeder ggplot2-Einsteiger macht, meist in Woche eins: eine wörtliche Farbe innerhalb von aes() zu setzen. Die Regel ist kurz - innerhalb von aes() heißt "variiert mit den Daten"; außerhalb heißt "feste Einstellung" - und die beiden Platzierungen tun völlig Verschiedenes:

# MAPPING: color varies by a column - each cylinder count gets its own
# color, and a legend appears automatically
ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
    geom_point(size = 2)

# SETTING: every point is literally steelblue - no legend, no mapping
ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point(color = "steelblue", size = 2)

Und die Falle selbst:

# WRONG: "blue" inside aes() is treated as data, not as a color
ggplot(mtcars, aes(x = wt, y = hp, color = "blue")) +
    geom_point()

Das zeichnet lachsrosa Punkte mit einer Legende, deren einziger Eintrag "blue" heißt. Warum: aes() bildet Spalten auf Eigenschaften ab, also erzeugt color = "blue" eine erfundene Ein-Kategorie-Spalte, deren Wert überall das Wort "blue" ist, und ggplot weist dieser Kategorie seine erste Standardfarbe zu - die zufällig ein rötliches Lachsrosa ist. Wenn du "mach die Punkte blau" meintest, gehört die Farbe außerhalb der Zuordnung: geom_point(color = "blue"). Dieselbe Regel gilt für size, shape, fill und alpha. (Beachte auch factor(cyl) im Zuordnungsbeispiel: cyl ist numerisch, und es in factor() zu packen verlangt eigene Farben je Gruppe statt eines kontinuierlichen Farbverlaufs.)

Beschriftungen, Facetten und Themes

labs() benennt alles an einer Stelle - und ein Diagramm ist nicht fertig, bevor es echte Beschriftungen hat:

ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
    geom_point(size = 2) +
    labs(title = "Horsepower vs. weight",
         x     = "Weight (1000 lbs)",
         y     = "Horsepower",
         color = "Cylinders")

Facetten sind ggplot2s Aushängeschild: Sie zerlegen ein Diagramm in Kleinmehrfachbilder, ein Feld pro Gruppe, mit gemeinsamen Achsen, sodass die Felder ehrlich vergleichbar sind:

ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point() +
    facet_wrap(~ cyl)

Drei Felder erscheinen - je eines für 4-, 6- und 8-Zylinder-Autos -, in einem Gitter angeordnet mit dem Gruppenwert als Beschriftung über jedem Feld. In Base R ist das eine par(mfrow)-Jonglage mit manuell gemeinsamen Grenzen; hier ist es eine Zeile. Facettierung belohnt aufgeräumte Daten, weshalb ggplot2 so natürlich mit einer dplyr-Pipeline zusammenpasst - filtern und zusammenfassen, dann das Ergebnis direkt in ggplot() pipen.

Themes gestalten die nicht-datentragende Tinte in einem Aufruf um: + theme_minimal() (sauberer weißer Hintergrund), + theme_bw(), + theme_classic() (nur Achsen, kein Gitter) oder die graue Voreinstellung. Wähl eines pro Projekt und bleib konsistent - ein Bericht, in dem jede Abbildung dasselbe Theme teilt, liest sich als ein Dokument statt als Sammelalbum.

Speichern mit ggsave() - und wann Base R weiterhin genügt

ggsave() schreibt das zuletzt erzeugte Diagramm auf die Festplatte und leitet das Format aus der Dateiendung ab:

ggsave("hp-vs-weight.png", width = 8, height = 5)          # last plot shown
ggsave("hp-vs-weight.pdf", plot = p, width = 8, height = 5) # a saved object

width und height sind standardmäßig in Zoll; setz sie explizit, denn Schriftgrößen skalieren mit den Ausgabemaßen, und die Voreinstellungen passen selten zu dem Ort, für den die Abbildung bestimmt ist.

Und wann sich der Aufwand lohnt: Für einen Fünf-Sekunden-Blick auf eine Variable während einer Analyse sind Base R's plot() und Co. weniger Tipparbeit und null Abhängigkeiten - es gibt keinen Preis dafür, überall ggplot2 zu nutzen. ggplot2 verdient sein Geld in dem Moment, in dem eine Abbildung Gruppen, Legenden, Facetten oder ein Publikum betrifft: Die Grammatik skaliert zu einer Komplexität, die Base-Plotting nur mit Mühe bewältigt.

Was du mitnimmst

  • ggplot2 setzt jedes Diagramm aus Daten + aes()-Zuordnung + geom-Schichten zusammen, verbunden mit +; lerne die Grammatik einmal, nutze sie für jeden Diagrammtyp wieder.
  • aes() bildet Spalten auf visuelle Eigenschaften ab - nackte Spaltennamen, ausgewertet in deinem Data Frame.
  • Innerhalb von aes() = variiert mit den Daten (und bekommt eine Legende); außerhalb = feste Einstellung. aes(color = "blue") ist der klassische Bug.
  • labs() für Titel, facet_wrap(~ group) für Kleinmehrfachbilder, theme_minimal() und Co. für die Gestaltung, ggsave() mit expliziten Maßen zum Exportieren.
  • Schneller Einzelblick: Base R. Gruppen, Facetten oder ein Publikum: ggplot2.

Damit schließt das Grafikkapitel - von hier ist der natürliche nächste Schritt die deskriptive Statistik, die den Formen, die diese Diagramme offenbaren, Zahlen gibt.

Häufig gestellte Fragen

Was ist ggplot2 in R?

ggplot2 ist R's beliebtestes Grafikpaket. Statt einer Funktion pro Diagrammtyp setzt du jedes Diagramm aus denselben drei Bausteinen zusammen - einem Data Frame, einer aes()-Zuordnung von Spalten zu visuellen Eigenschaften und einer oder mehreren geom_*()-Schichten -, verbunden mit +. Es ist Teil des Tidyverse.

Wie installiert man ggplot2?

Führ einmal install.packages("ggplot2") aus, dann library(ggplot2) am Anfang jedes Skripts, das es nutzt. Das Installieren legt das Paket auf deinen Rechner; library() lädt es in die aktuelle Sitzung.

Was macht aes() in ggplot2?

aes() bildet Spalten deiner Daten auf visuelle Eigenschaften ab: aes(x = wt, y = hp, color = factor(cyl)) sagt, dass die horizontale Position aus wt kommt, die vertikale aus hp und die Punktfarbe aus der Zylinderzahl. Alles innerhalb von aes() variiert mit den Daten; alles außerhalb ist eine feste Einstellung.

Warum haben meine ggplot-Punkte nicht die Farbe, die ich wollte?

Du hast die Farbe in aes() gesetzt: aes(color = "blue") setzt keine Farbe, sondern bildet eine erfundene Kategorie namens "blue" ab, sodass ggplot seine eigene Standardfarbe wählt und eine Legende ergänzt. Um eine wörtliche Farbe zu setzen, schreib sie außerhalb der Zuordnung: geom_point(color = "blue").

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S