library(ggplot2)
Allgemeines
Im Gegensatz zum Base-Plotting-System muss das Paket ggplot2
installiert und aktiviert werden:
Dieses Paket ist eine Implementierung der sogenannten Grammar of Graphics, welche statistische Grafiken mit einheitlichen grundlegenden Elementen zu beschreiben versucht. Dies hat den Vorteil, dass man mit dieser Grammatik die unterschiedlichsten Grafiken zusammenbauen kann und nicht für jede Darstellung einen anderen Befehl benötigt.
Aufbau einer Grafik
Eine Grafik in ggplot2
besteht aus verschiedenen Ebenen. Jede Ebene beinhaltet geometrische Elemente (Geoms genannt) – z.B. Balken, Linien oder Text. Geoms haben ästhetische Eigenschaften (kurz Aes genannt), welche das Aussehen von Geoms bestimmen (beispielsweise die Position von Punkten, Farben oder Linienstile). Diese ästhetischen Eigenschaften werden aus Spalten eines Data Frames bestimmt, d.h. man erstellt ein Mapping zwischen den Daten und passenden Aes. Das folgende Bild veranschaulicht den Ebenencharakter einer Grafik in ggplot2
:
Die ggplot()
-Funktion
Erstellen wir einige beispielhafte Grafiken mit dem in R verfügbaren Datensatz airquality
. Diese Daten beinhalten diverse Luftgütemessungen in New York im Zeitraum Mai bis September 1973 (siehe dazu ?airquality
). Es ist sinnvoll, wenn wir zunächst aus den beiden Spalten Month
und Day
eine neue Spalte namens date
erzeugen:
$date = as.Date(
airqualitypaste(airquality$Month, airquality$Day, "1973"),
format="%m %d %Y"
)
Eine Grafik in ggplot2
beginnt immer mit der ggplot()
-Funktion. Hier ist nun der Aufbau einer Grafik von Bedeutung – d.h. es ist wichtig zu wissen, dass sich eine Grafik aus mehreren Ebenen zusammensetzt. Man beginnt also immer mit der Spezifikation der Grafik, d.h. man legt das Data Frame fest, aus dem die darzustellenden Spalten stammen. Außerdem gibt man die Spalten aus diesem Data Frame an, die man durch Zuweisen gewünschter ästhetischer Eigenschaften plotten möchte.
Im ersten Schritt legen wir also das Data Frame und die Spalten fest:
ggplot(airquality, aes(x=Wind, y=Ozone))
Hier ist anzumerken, dass die darzustellenden Spalten innerhalb der Funktion aes()
angegeben werden müssen. Weiters kann man (so wie bei allen Funktionsaufrufen) die Namen der übergebenen Funktionsargumente explizit angeben (data
und mapping
), dann ist die Zuordnung bzw. Bedeutung der Argumente sofort klar:
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone))
Die Spalte Wind
wird also auf die ästhetische Eigenschaft x
abgebildet (also entlang der x-Achse dargestellt), die Spalte Ozone
analog auf die ästhetische Eigenschaft y
.
Die eigentlichen Daten werden aber noch nicht dargestellt, denn wir haben noch nicht spezifiziert, wie die Daten gezeichnet werden sollen. Dafür benötigt man eine neue Ebene mit den gewünschten Geoms. In unserem Beispiel möchten wir Punkte zeichnen, d.h. wir verwenden geom_point()
dafür und fügen diese mit +
zur ersten Ebene hinzu:
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone)) +
geom_point()
Der Zeilenumbruch ist hier (wie in alle R-Befehlen) nicht notwendig, erhöht aber die Übersicht, weil man so eine Ebene pro Zeile darstellen kann.
In weiteren Ebenen kann man dann Titel und Achsenbeschriftungen ändern/hinzufügen:
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone)) +
geom_point() +
ggtitle("Wind vs. Ozone") +
xlab("Wind (mph)") +
ylab("Ozone (ppb)")
Alternativ könnte man alle drei Beschriftungen mit der Funktion labs()
hinzufügen:
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone)) +
geom_point() +
labs(title="Wind vs. Ozone", x="Wind (mph)", y="Ozone (ppb)")
In einer weiteren Ebene kann man dann eine Regressionsgerade (einen sogenannten “Smoother”) hinzufügen:
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone)) +
geom_point() +
labs(title="Wind vs. Ozone", x="Wind (mph)", y="Ozone (ppb)") +
geom_smooth(method="lm", formula="y ~ x")
Möchte man die Punkte z.B. für den Monat Mai (entspricht dem Wert 5) hervorheben (die Regressionsgerade aber für alle Punkte belassen), kann man innerhalb geom_point()
eine lokale Ästhetik color
definieren, welche dem logischen Vektor Month == 5
entspricht (also TRUE
für alle Zeilen in denen die Spalte Month
den Wert 5
hat und FALSE
in allen anderen Fällen):
ggplot(data=airquality, mapping=aes(x=Wind, y=Ozone)) +
geom_point(mapping=aes(color=Month==5)) +
geom_smooth(method="lm", formula="y ~ x") +
labs(title="Ozone and Wind in NYC")
Dieses lokale Mapping wird dem globalen Mapping (innerhalb von ggplot()
) hinzugefügt.
Es gibt eine große Anzahl an Elementen, aus denen man die unterschiedlichsten Grafiken zusammenbauen kann. Die offizielle ggplot2-Website hat eine vollständige Liste aller Geoms, Aesthetics und anderer Befehle. Im Folgenden sehen wir uns noch an, wie man Histogramme, Boxplots und Fehlerbalkenplots erzeugen kann.
Eine Liniengrafik erzeugt man mit geom_line()
:
ggplot(data=airquality, mapping=aes(x=date, y=Ozone)) +
geom_line()
Ein Histogramm erstellt man mit geom_histogram()
:
ggplot(data=airquality, mapping=aes(x=Ozone)) +
geom_histogram() + ylab("")
Auch hier kann man die Bingröße manuell angeben:
ggplot(data=airquality, mapping=aes(x=Ozone)) +
geom_histogram(binwidth=10) + ylab("")
Boxplots können mit geom_boxplot()
erzeugt werden. Um Boxplots gleichzeitig für alle Stufen eines Faktors darzustellen, muss man dies wie folgt spezifizieren (die Spalte Month
wird zur Darstellung auf der x-Achse in einen Faktor konvertiert):
ggplot(data=airquality, mapping=aes(x=factor(Month), y=Ozone)) +
geom_boxplot() + xlab("Month")
Um einen Fehlerbalkenplot zu erstellen (der die Mittelwerte und deren 95%-Konfidenzintervalle zeigt), kann man die Funktion stat_summary()
benutzen. Für diese Grafik muss außerdem das Paket Hmisc
installiert sein.
library(Hmisc)
ggplot(data=airquality, mapping=aes(x=factor(Month), y=Ozone)) +
stat_summary(fun=mean, geom="point") +
stat_summary(fun.data=mean_cl_normal, geom="errorbar", width=0.2) +
xlab("Month")
Themes
Wenn man mit dem generellen Stil der Grafiken nicht zufrieden ist, kann man ein anderes vordefiniertes Theme verwenden. Folgende Themes stehen zur Auswahl:
theme_gray()
theme_bw()
theme_linedraw()
theme_light()
theme_dark()
theme_minimal()
theme_classic()
theme_void()
Man aktiviert ein Theme indem man es als eigene Ebene zu einer vorhandenen Grafik hinzufügt:
ggplot(airquality, aes(x=factor(Month), y=Ozone)) +
stat_summary(fun=mean, geom="point") +
stat_summary(fun.data=mean_cl_normal, geom="errorbar", width=0.2) +
xlab("Month") +
theme_minimal()
Alternativ kann man mit der Funktion theme_set()
ein Theme auch global für alle Grafiken setzen. Alle Grafiken, die danach erzeugt werden, verwenden diesen Stil. Das folgende Beispiel setzt theme_minimal()
als Standard-Theme:
theme_set(theme_minimal())
Patchwork
Möchte man mehrere Grafiken in einem Plot darstellen, bietet sich das Paket patchwork
an. Damit kann man Grafiken sehr einfach zu beliebigen Layouts kombinieren:
library(patchwork)
= ggplot(airquality, aes(x=date, y=Ozone)) + geom_line() + geom_point()
p1 = ggplot(airquality, aes(x=Wind, y=Ozone, color=Month==5)) + geom_point()
p2 = ggplot(mpg, aes(x=factor(cyl), y=cty)) + geom_boxplot()
p3
/ (p2 + p3) p1
Dabei kennzeichnet /
eine neue Zeile und +
eine neue Spalte.
Übungen
Übung 1
Laden Sie den Datensatz penguins
aus dem Paket palmerpenguins
und erstellen Sie einen Scatterplot der Spalten bill_length_mm
auf der x-Achse und bill_depth_mm
auf der y-Achse. Fügen Sie eine Regressionsgerade hinzu. Beschriften Sie die Achsen mit aussagekräftigen Bezeichnungen.
Übung 2
Laden Sie den Datensatz penguins
aus dem Paket palmerpenguins
und erstellen Sie einen Scatterplot der Spalten bill_length_mm
auf der x-Achse und bill_depth_mm
auf der y-Achse. Stellen Sie die Punkte der drei Spezies in unterschiedlichen Farben dar. Beschriften Sie die Achsen mit aussagekräftigen Bezeichnungen.
Vergleichen Sie die Regressionsgeraden der einzelnen Spezies mit der Gerade über die gesamten Daten aus Übung 1 – fällt Ihnen etwas auf (Stichwort Simpson-Paradoxon)?
Übung 3
Laden Sie den in R integrierten Datensatz Orange
und stellen Sie die Abhängigkeit des Stammumfanges circumference
(y-Achse) vom Alter age
(x-Achse) grafisch dar. Stellen Sie die Daten als Punkte dar und verbinden Sie außerdem die Daten eines jeden Baumes (d.h. Sie sollten dann 5 Linien gleichzeitig darstellen, am besten in unterschiedlichen Farben indem Sie das Mapping color=Tree
verwenden).
Übung 4
Verwenden Sie den Datensatz mpg
, welcher automatisch mit ggplot2
geladen wird. Wie hängt der Hubraum displ
mit dem Kraftstoffverbrauch hwy
zusammen? Beantworten Sie diese Frage mit einem Scatterplot und überlagerter Regressionsgerade.
Übung 5
Verwenden Sie den Datensatz mpg
und erstellen Sie einen Boxplot, in dem Sie den Kraftstoffverbrauch in Liter pro 100 Kilometer (l/100km) der Zylinderanzahl gegenüberstellen. Erstellen Sie dazu eine neue Spalte l100km
im Data Frame mpg
, die den Kraftstoffverbrauch in l/100km aus der Spalte hwy
(in Meilen pro Gallone, MPG) berechnet. Sie erhalten diesen Verbrauch mit folgender Formel:
\[\text{Verbrauch (in l/100km)} = \frac{235}{\text{Verbrauch (in MPG)}}\]
Übung 6
Welches Problem hat die Grafik, die Sie in Übung 4 erstellt haben? Wie können Sie dieses Problem mit ggplot2
umgehen? Sehen Sie sich die Werte der displ
-Spalte an. In diesem Zusammenhang könnte geom_jitter()
hilfreich sein.
Übung 7
Betrachten Sie folgenden Scatterplot mit überlagerter Regressionsgeraden:
library(tibble)
= tibble(x=1:10, y=1:10)
df
ggplot(data=df, mapping=aes(x=x, y=y)) +
geom_point(size=4) +
geom_smooth(method="lm", formula="y ~ x")
Die Punkte werden von der Regressionsgeraden überdeckt – wie kann man das verhindern? Die Gerade soll also “hinter” den Punkten gezeichnet werden.