class: center, middle, inverse, title-slide # Datenvisualisierung --- # Roslings Bubble Chart <iframe width="800" height="450" src="https://www.youtube.com/embed/Z8t4k0Q8e8Y" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> .small[Quelle: Hans Rosling auf Youtube: https://youtu.be/Z8t4k0Q8e8Y] --- ## Roslings Bubble Chart ![Hans Roslings Bubble Chart](./figs/rosling.gif) --- ## Einführung in ggplot2 - Grafiken nutzen zur Veranschaulichung von Sachverhalten - Explorative Datenanalyse um die Daten kennen zu lernen - wird häufig vernachlässigt - Fehler oder unerwartete Probleme können häufig durch eingehende visuelle Datenanalyse vermieden werden - Nutzen des Pakets [`ggplot2`](http://ggplot2.org) und `dplyr` - Das [Cheat Sheet](https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf) zu ggplot2 - Ein deutsches [Cheat Sheet](https://www.rstudio.com/wp-content/uploads/2015/06/ggplot2-german.pdf) --- ## Komponenten in ggplot2 - **Daten**: In unserem Beispiel bisher immer der `Datensatz` Datensatz - **Geometry**: Verschiedene Arten von Grafiken, z.B. Streudiagramm, Boxplot, Histogramm, Kerndichteschätzung - **Aesthetic**: Definieren was die x-Achse und was die y-Achse zeigen soll. Weiterhin können wir Farben und Formen unserer Grafik bestimmen, alles abhängig von der **Geometry**, welche wir wählen - **scale**: Definieren wie die Skalierung unserer x-Achse und y-Achse sein soll (eventuell logarithmisch?) Mittels der nächsten Folien wollen wir eine Grafik Schritt für Schritt erzeugen --- ## Generierung eines leeren `ggplot` Objekts Zuerst generieren wir uns ein leeres `ggplot` Objekt, in welchem wir definieren, welche Daten wir zeigen wollen. - Dadurch erhalten wir eine graue Box, welche von ggplot gerendet wurde ```r Datensatz <- readRDS("data/Gapminder_1800-2020.rds") ggplot(data = Datensatz) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/ggplot-example-1-1.png" width="70%" style="display: block; margin: auto;" /> --- ## Layer In diese graue Box können wir nun eine Grafik einbetten Es gibt verschiedene Layer (Grafikarten) die wir verwenden können (hier einige Beispiele): - geom_bar, geom_point, geom_line, geom_smooth, geom_histogram, geom_boxpolot, geom_density Um einen Layer hinzuzufügen nutzen wir das `+` Symbol. Code könnte entsprechend so aussehen: >> DATENSATZ %>% `ggplot()` + LAYER 1 + LAYER 2 + ... --- ## Layer Angenommen Sie wollen ein Streudiagramm erzeugen, dann können Sie schauen, welcher Layer dafür geeignet ist. Das Cheat Sheet sagt uns, dass `geom_point` dafür geeignet ist. Anschließend sollten Sie wissen, wie viele Argumente ihre Grafik benötigt um dargestellt werden zu können: - Gehen Sie zu der Hilfeseite von `?geom_point` und scrollen Sie zu der Überschrift `Aesthetics` um mehr darüber zu erfahren - Ein Streudiagramm benötigt mindestens zwei Argumente `x` und `y` --- ## Die Aesthetics Funktion `aes` Mittels der Funktion `aes` kann anschließend die Grafik auf Grundlage der Daten erstellt werden - `aes` wird oft als Argument einer Geometry Funktion verwendet Beispiel für ein Streudiagramm mit Einkommen und Lebenserwartung für das Jahr 1800: ```r Datensatz %>% filter(Jahr == 1800) %>% ggplot() + geom_point(aes(x = Einkommen, y = Lebenserwartung)) ``` - `x =` und `y =` können wir hier auch weg lassen - Die ersten zwei Argumente werden von ggplot automatisch als `x` und `y` aufgefasst - Skalierung und Benennung erfolgen automatisch, wenn nicht anders spezifiziert --- ## Die Aesthetics Funktion `aes` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-4-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Zusätzliche Layer In manchen Fällen möchten wir gerne einen zusätzlichen Layer in unsere Grafik einfügen. Beispielsweise wollen wir jedem Datenpunkt ein Label geben, welches genau beziffert um welchen Wert es sich handelt. - Möglich mit `geom_label` and `geom_text` - Durch den `label` Befehl in `aes` können wir dies umsetzen - **Beachten:** Das `label` Argument muss innerhalb von `aes` aufgerufen werden, ansonsten bekommen Sie einen Fehler Ein Beispiel auf der nächsten Folie ```r library(ggthemes) library(ggrepel) Datensatz %>% filter(Jahr == 1800) %>% ggplot() + geom_point(aes(Einkommen, Lebenserwartung)) + geom_text(aes(Einkommen, Lebenserwartung, label=country)) ``` --- ## Zusätzliche Layer <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-6-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Weitere Argumente - Jede Geometry Funktion hat ihre individuellen Argumente neben `aes` und `data` - Beispielsweise kann über `size` die Größe der Punkte im Streudiagramm verändert werden ```r Datensatz %>% filter(Jahr == 1800) %>% ggplot() + geom_point(aes(Einkommen, Lebenserwartung), size = 3) + geom_text(aes(Einkommen, Lebenserwartung, label=country)) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-7-1.png" width="25%" style="display: block; margin: auto;" /> --- ## Weitere Argumente - `size` betrifft hier alle Punkte im Streudiagramm und ist nicht in der `aes` enthalten - Sie können `size` jedoch auch auf der Basis einer anderen Variable definieren, z.B. der Bevölkerungszahl - Nun muss die Definition von `size` jedoch innerhalb der `aes` erfolgen, da auf den Datensatz zurückgegriffen werden soll ```r Datensatz %>% filter(Jahr == 1800) %>% ggplot() + geom_point(aes(Einkommen, Lebenserwartung, size = Bevoelkerung)) + geom_text(aes(Einkommen, Lebenserwartung, label=country)) ``` --- ## Weitere Argumente <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-9-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Weitere Argumente - Leider können wir durch größere Punkte die Labels nicht mehr lesen - Aus der Hilfeseite von `?geom_text` erfahren wir, wie die Labels verändert werden können: - Durch `nudge_x` können die Labels etwas nach rechts abgesetzt werden - Durch `nudge_y` können die Labels etwas nach oben abgesetzt werden --- ## Weitere Argumente <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-10-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Globale `aes` Abbildungen - Im vorherigen Beispiel hatten wir `aes(Einkommen, Lebenserwartung)` doppelt verwendet - Wir können statt dessen auch eine _globale_ aesthetic Abbildung erstellen - Dies wird erreicht, indem wir als erstes eine _Grafikvorlage_ erstellen und uns eine _globale_ `aes` definieren Wir speichern unsere _Grafikvorlage_ in `p`: .small[ ```r p <- Datensatz %>% filter(Jahr == 1800) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, label = country, size = Bevoelkerung)) ``` ] --- ## Globale `aes` Abbildungen Anschließend verändern wir unser Vorlage `p` wie wir es wünschen - Hier verändern wir nur die Größe der Punkte und Position der Labels ```r p + geom_point() + geom_text(nudge_y = 2) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-12-1.png" width="30%" style="display: block; margin: auto;" /> --- ## Lokale `aes` überschreiben globale `aes` - Wir können diese _globalen_ Abbildungen durch _lokale_ überschreiben - Beispielsweise können wir den Text _Die Menschen damals wurden nicht alt!_ auf Höhe der x-Achse bei 1500 und der y-Achse bei 50 platzieren: ```r p + geom_point(size = 3) + geom_text(aes(x = 1500, y = 46, label = "Die Menschen damals wurden nicht alt!")) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-13-1.png" width="25%" style="display: block; margin: auto;" /> --- ## Skalierung - Falls eine andere Skalierung gewünscht wird - durch `scale_x_continous` verändern wir die x-Achse - durch `scale_y_continous` verändern wir die y-Achse - durch `scale_x_log10()` verändern wir die x-Achse zu logarithmierter Skala - durch `scale_y_log10()` verändern wir die y-Achse zu logarithmierter Skala --- ## Skalierung ```r p + geom_point() + geom_text(nudge_y = 0.1) + scale_x_log10() ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-14-1.png" width="35%" style="display: block; margin: auto;" /> --- ## Titel und Label - Titel oder Label können wir durch `ggtitle` bzw. `xlab`, `ylab` verändern: ```r p + geom_point() + geom_text(nudge_y = 2) + scale_x_log10() + xlab("Einkommen") + ylab("Lebenserwartung") + ggtitle("Roslings Bubble Chart für das Jahr 1800") ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-15-1.png" width="25%" style="display: block; margin: auto;" /> --- ## Farben - Durch das Argument `col` innerhalb von `geom_point` kann die Farbe der Punkte verändert werden - Erstellen wir uns der einfachheit halber eine neue Grafikvorlage: .small[ ```r p <- Datensatz %>% filter(Jahr == 1800) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, label = country, size = Bevoelkerung)) + geom_text(nudge_y = 5) + scale_x_log10() + xlab("Einkommen") + ylab("Lebenserwartung") + ggtitle("Roslings Bubble Chart für das Jahr 1800") ``` ] --- ## Farben - Nun sollen alle Punkte blau sein ```r p + geom_point(color = "blue") ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-17-1.png" width="35%" style="display: block; margin: auto;" /> --- ## Farben - Nicht unbedingt unser Ziel - _Besser:_ Bestimmte Farben für bestimmte Gruppen - **Schön bei `ggplot2`:** Wir können `ggplot2` eine katogoriale Variable angeben: - nun werden automatisch unterschiedliche Farben für alle Gruppen dieser Variablen zugeteilt - es wird automatisch eine Legende erzeugt --- ## Farben ```r p + geom_point(aes(color=continent)) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-18-1.png" width="40%" style="display: block; margin: auto;" /> --- ## Nur bestimmte Länder beschriften - Es sollen nun nicht alle Ländern, sondern nur China, Somalia, Deutschland und die USA beschriftet werden. .small[ ```r p <- Datensatz %>% filter(Jahr == 1800) %>% mutate(annotation = case_when( country %in% c("China", "Somalia", "Germany", "United States") ~ "yes") ) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, label = country, size = Bevoelkerung)) + geom_point(aes(color=continent)) + geom_text(data = . %>% filter(annotation=="yes"), aes(label=country), size=4) + scale_x_log10() + xlab("Einkommen") + ylab("Lebenserwartung") + ggtitle("Roslings Bubble Chart für das Jahr 1800") p ``` ] --- ## Nur bestimmte Länder beschriften <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-20-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Die Größe der Länderpunkte - Nun können Sie noch die Größe der Kreise etwas besser skalieren. - Hier soll die Bevölkerung des größten Landes 20 mal so groß dargestellt werden wie das kleineste Land ```r p <- p + scale_size(range = c(1, 20)) p ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-21-1.png" width="30%" style="display: block; margin: auto;" /> --- ## Farbpalette und Legende - Es gibt in ggplot verschiedenste Farbpaletten, hier soll die Farbpalette von viridis verwendet werden ```r library(viridis) p + scale_color_viridis(discrete=TRUE) + theme(legend.position="none") ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-22-1.png" width="30%" style="display: block; margin: auto;" /> --- ## Code für die Grafik aus dem Jahr 1800 - Gesamter Code für die Grafik .small[ ```r Datensatz %>% filter(Jahr == 1800) %>% mutate(annotation = case_when( country %in% c("China", "Somalia", "Germany", "United States") ~ "yes") ) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, label = country, size = Bevoelkerung)) + geom_point(aes(color=continent)) + geom_text(data = . %>% filter(annotation=="yes"), aes(label=country), size=4) + scale_x_log10() + xlab("Einkommen") + ylab("Lebenserwartung") + ggtitle("Roslings Bubble Chart für das Jahr 1800") + scale_size(range = c(1, 20)) + scale_color_viridis(discrete=TRUE) + theme(legend.position="none") ``` ] --- ## Code für die Grafik aus dem Jahr 1800 <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-24-1.png" width="45%" style="display: block; margin: auto;" /> --- ## Animation für mehrere Jahre ![Hans Roslings Bubble Chart](./figs/rosling.gif) --- ## Zusätzliche Pakete - Weiterhin gibt es bei `ggplot2` Zusatzpakete, durch welche wir noch einige Dinge verändern können - Durch die zusätzlichen Pakete `ggthemes` und `ggrepel` können wir unserer Grafik noch final bearbeiten - Beispielsweise können wir unsere Grafik mit einem anderen Grundlayout ausstatten - Hier dem Thema `theme_fivethirtyeight()` - [Hier](https://github.com/jrnold/ggthemes) finden Sie weitere Themen für ihre Grafik --- ## Zusätzliche Pakete - Das Paket `ggrepel` stellt sicher, dass die Label eines Punktes nicht übereinander gezeigt werden - In unserem Beispiel schwer umzusetzen, da hier sehr viele Labels vorhanden sind - Grundsätzlich kann dies jedoch durch das laden des Pakets `ggrepel` erreicht werden - In der Grafik muss dann nur noch `geom_text` durch `geom_text_repel` ersetzt werden --- ## Mehrere Grafiken nebeneinander Sie wollen mehrere Grafiken nebeneinander platzieren - Hier hilft ihnen das Paket `gridExtra` - Mit der Funktion `grid.arrange` aus `gridExtra` werden die Schaubilder nebeneinander gezeigt: .small[ ```r p1 <- Datensatz %>% filter(Jahr == 1800) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, size=Bevoelkerung, color=continent)) + geom_point() + theme(legend.position="none") p2 <- Datensatz %>% filter(Jahr == 2018) %>% ggplot(aes(x = Einkommen, y = Lebenserwartung, size=Bevoelkerung, color=continent)) + geom_point() + theme(legend.position="none") ``` ] --- ## Mehrere Grafiken nebeneinander ```r library(gridExtra) grid.arrange(p1,p2, ncol = 2) ``` <img src="Visualisierung_mit_ggplot2_files/figure-html/unnamed-chunk-26-1.png" width="35%" style="display: block; margin: auto;" /> **Achtung:** Hier sind die Achsen für beide Grafiken nicht gleich! Diese müssen bei vergleichenden Schaubildern immer einheitlich formatiert sein!