library("readr")
library("lubridate")
library("dplyr")
library("ggplot2")
library("tidyr")
Infovis 1: Demo
Als erstes laden wir den Datensatz temperature_SHA_ZER.csv ein. Es handelt sich dabei um eine leicht modifizierte Variante der Daten aus PrePro1 und PrePro2.
# Wir können den Datensatz direkt über die URL einladen oder aber ihr nutzt die
# URL um den Datensatz lokal bei euch abzuspeichern und wie gewohnt einzulesen
<- read_delim("datasets/infovis/temperature_SHA_ZER.csv", ",") temperature
time | SHA | ZER |
---|---|---|
2000-01-01 00:00:00 | 0.2 | -8.8 |
2000-01-01 01:00:00 | 0.3 | -8.7 |
2000-01-01 02:00:00 | 0.3 | -9.0 |
2000-01-01 03:00:00 | 0.3 | -8.7 |
2000-01-01 04:00:00 | 0.4 | -8.5 |
2000-01-01 05:00:00 | 0.5 | -8.4 |
Ggplot2
Ein ggplot
wird mit dem Befehl ggplot()
initiiert. Hier wird einerseits der Datensatz festgelegt, auf dem der Plot beruht (data =
), sowie die Variablen innerhalb des Datensatzes, die Einfluss auf den Plot ausüben (mapping = aes()
).
# Datensatz: "temperature" | Beeinflussende Variablen: "time" und "temp"
ggplot(data = temperature, mapping = aes(time, SHA))
Weiter braucht es mindestens ein “Layer”, der beschreibt, wie die Daten dargestellt werden sollen (z.B. geom_point()
). Anders als bei “Piping” (|>
) wird ein Layer mit +
hinzugefügt.
ggplot(data = temperature, mapping = aes(time, SHA)) +
# Layer: "geom_point" entspricht Punkten in einem Scatterplot
geom_point()
Da ggplot die Eingaben in der Reihenfolge data =
und dann mapping =
erwartet, können wir diese Spezifizierungen auch weglassen.
ggplot(temperature, aes(time, SHA)) +
geom_point()
Long vs. wide
Wie wir in PrePro 2 bereits erwähnt haben, ist ggplot2
auf long tables ausgelegt. Wir überführen deshalb an dieser Stelle die breite in eine lange Tabelle:
<- pivot_longer(temperature, -time, names_to = "station", values_to = "temp") temperature_long
Nun wollen wir die Stationen unterschiedlich einfärben. Da wir Variablen definieren wollen, welche Einfluss auf die Grafik haben sollen, gehört diese Information in aes()
.
ggplot(temperature_long, aes(time, temp, colour = station)) +
geom_point()
Wir können noch einen Layer mit Linien hinzufügen:
ggplot(temperature_long, aes(time, temp, colour = station)) +
geom_point() +
geom_line()
Beschriftungen (labels)
Weiter können wir die Achsen beschriften und einen Titel hinzufügen. Zudem lasse ich die Punkte (geom_point()
) nun weg, da mir diese nicht gefallen.
ggplot(temperature_long, aes(time, temp, colour = station)) +
geom_line() +
labs(
x = "Zeit",
y = "Temperatur in °C",
title = "Temperaturdaten Schweiz",
subtitle = "2001 bis 2002",
color = "Station"
)
Split Apply Combine
Im obigen Plot fällt auf, dass stündliche Werte eine zu hohe Auflösung haben, wenn wir die Daten über 2 Jahre visualisieren. Mit Split Apply Combine (PrePro 3) können wir die Auflösung unserer Daten verändern:
<- temperature_long |>
temperature_day mutate(time = as.Date(time))
temperature_day## # A tibble: 35,088 × 3
## time station temp
## <date> <chr> <dbl>
## 1 2000-01-01 SHA 0.2
## 2 2000-01-01 ZER -8.8
## 3 2000-01-01 SHA 0.3
## 4 2000-01-01 ZER -8.7
## 5 2000-01-01 SHA 0.3
## 6 2000-01-01 ZER -9
## 7 2000-01-01 SHA 0.3
## 8 2000-01-01 ZER -8.7
## 9 2000-01-01 SHA 0.4
## 10 2000-01-01 ZER -8.5
## # ℹ 35,078 more rows
<- temperature_day |>
temperature_day group_by(station, time) |>
summarise(temp = mean(temp))
temperature_day## # A tibble: 1,462 × 3
## # Groups: station [2]
## station time temp
## <chr> <date> <dbl>
## 1 SHA 2000-01-01 1.25
## 2 SHA 2000-01-02 1.73
## 3 SHA 2000-01-03 1.59
## 4 SHA 2000-01-04 1.78
## 5 SHA 2000-01-05 4.66
## 6 SHA 2000-01-06 3.49
## 7 SHA 2000-01-07 3.87
## 8 SHA 2000-01-08 3.28
## 9 SHA 2000-01-09 3.24
## 10 SHA 2000-01-10 3.24
## # ℹ 1,452 more rows
X/Y-Achse anpassen
Man kann auch Einfluss auf die x-/y-Achsen nehmen. Dabei muss man zuerst festlegen, was für ein Achsentyp der Plot hat (vorher hat ggplot
eine Annahme auf der Basis der Daten getroffen).
Bei unserer y-Achse handelt es sich um numerische Daten, ggplot
nennt diese: scale_y_continuous()
. Unter ggplot2.tidyverse.org findet man noch andere x/y-Achsentypen (scale_x_irgendetwas
bzw. scale_y_irgendetwas
).
ggplot(temperature_day, aes(time, temp, colour = station)) +
geom_line() +
labs(
x = "Zeit",
y = "Temperatur in °C",
title = "Temperaturdaten Schweiz",
subtitle = "2001 bis 2002",
color = "Station"
+
) scale_y_continuous(limits = c(-30, 30)) # y-Achsenabschnitt bestimmen
Das gleiche Spiel kann man für die x-Achse betreiben. Bei unserer x-Achse handelt es sich ja um Datumsangaben. ggplot
nennt diese: scale_x_date()
.
ggplot(temperature_day, aes(time, temp, colour = station)) +
geom_line() +
labs(
x = "Zeit",
y = "Temperatur in °C",
title = "Temperaturdaten Schweiz",
subtitle = "2001 bis 2002",
color = "Station"
+
) scale_y_continuous(limits = c(-30, 30)) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b"
)
Facets / Small Multiples
Sehr praktisch sind auch die Funktionen für “Small multiples”. Dies erreicht man mit facet_wrap()
(oder facet_grid()
, mehr dazu später). Man muss mit einem Tilde-Symbol “~
” nur festlegen, welche Variable für das Aufteilen des Plots in kleinere Subplots verantwortlich sein soll.
ggplot(temperature_day, aes(time, temp, colour = station)) +
geom_line() +
labs(
x = "Zeit",
y = "Temperatur in °C",
title = "Temperaturdaten Schweiz",
subtitle = "2001 bis 2002",
color = "Station"
+
) scale_y_continuous(limits = c(-30, 30)) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b"
+
) facet_wrap(~station)
Auch facet_wrap
kann man auf seine Bedürfnisse anpassen: Beispielweise kann man mit ncol =
die Anzahl Facets pro Zeile bestimmen.
Zudem brauchen wir die Legende nicht mehr, da der Stationsname über jedem Facet steht. Ich setze deshalb theme(legend.position="none")
<- ggplot(temperature_day, aes(time, temp, colour = station)) +
p geom_line() +
labs(
x = "Zeit",
y = "Temperatur in °C",
title = "Temperaturdaten Schweiz",
subtitle = "2001 bis 2002"
+
) scale_y_continuous(limits = c(-30, 30)) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b"
+
) facet_wrap(~station, ncol = 1) +
theme(legend.position = "none")
p
Themes
Bisher haben wir die Standardeinstellung für das Kreieren der Plots genutzt. In diesem Abschnitt zeigen wir, wie du Plots individuell mit sogenannten Themes anpassen kannst.
Nun wollen wir mit einer von ggplot2 zur Verfügung gestellten Theme unseren Plot anpassen. Wir benutzen hier theme_classic(), weitere Themes findet ihr hier.
+ theme_classic() p
Fast alle Aspekte eines Plots können auch individuell angepasst werden. Jürgen Dengler und sein Team empfehlen folgende Anpassungen:
<-
mytheme theme_classic() +
theme(axis.line = element_line(linewidth = 0.6, color = "black"),
axis.text = element_text(size = 11, color = "black"),
axis.title = element_text(size = 13, color = "black"),
axis.ticks = element_line(linewidth = 0.6, color = "black"),
axis.ticks.length = unit(0.2, "cm"),
axis.title.y = element_text(vjust = +2),
axis.title.x = element_text(vjust = -2),
plot.title = element_text(hjust = 0.5, size = 13),
plot.subtitle = element_text(hjust = 0.5, size = 10),
plot.margin = margin(t = 4, r = 6, b = 6, l = 8, unit = "pt")
)
+ mytheme p
Plot exportieren
Folgendermassen könnt ihr den letzten Plot als PNG-Datei abspeichern:
ggsave(filename = "plot.png")