forked from CorrelAid/rlernen_umwelt
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path09_datenvisualisierung.Rmd
More file actions
550 lines (426 loc) · 30 KB
/
09_datenvisualisierung.Rmd
File metadata and controls
550 lines (426 loc) · 30 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
---
title: "Datenvisualisierung"
author: CorrelAid e.V.
date: "`r Sys.Date()`"
authors:
- Cosima Meyer
- Lennart Kasserra
- Jonas Lorenz
output:
html_document:
toc: true
toc_depth: 2
toc_float: true
theme: flatly
css: www/style.css
includes:
after_body: ./www/favicon.html
language: de
runtime: shiny_prerendered
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE)
library(learnr)
library(gradethis)
library(dplyr)
library(ggplot2)
library(ggbeeswarm)
library(countrycode)
library(leaflet)
library(tidyr)
library(plotly)
source("R/setup/gradethis-setup.R")
source("R/setup/tutorial-setup.R")
# Read app parameters
params <- yaml::yaml.load_file("www/app_parameters.yml")
# Benötigte Daten laden
source("R/setup/functions.R")
community <- get_community()
polygons_welt <- get_poly_welt()
karten_daten <- get_karten_daten(
from = community,
join = polygons_welt
)
```
```{r results='asis'}
cat(get_license_note(rmarkdown::metadata$title, rmarkdown::metadata$authors))
```

# **Einführung**
## **Zusammenfassung**
- **Vereinfachen und Beschleunigen** der Vermittlung (komplexer) Inhalte, weil Menschen visuelle Zusammenhänge oft schneller begreifen können als Text.
- Helfen bei der **Erkennung von Datenmustern** (z.B. zur Verteilung von und zu Beziehungen zwischen Variablen).
- Ermöglichen eine schnelle **Identifizierung von Fehlern und Ausreißern**.
- Interaktive Gestaltungsoptionen ermöglichen die **Entwicklung spannender Narrative (sog. Storytelling)** - nicht zuletzt werden sie deshalb auch häufig im [Datenjournalismus](https://www.mzes.uni-mannheim.de/socialsciencedatalab/article/telling-stories-with-data/){target="_blank"} genutzt.
- Die Entscheidung für eine **Visualisierungsart** hängt von vielen Faktoren ab:
- **Art der Variablen** (kontinuierlich oder diskret)
- **Anzahl an Variablen**, die visualisiert werden sollen
- **Botschaft**, die vermittelt werden soll
- Falls Ihr Probleme dabei habt, Euch für die passende Darstellungsform zu entscheiden, dann schaut doch gerne einmal auf der Website [From-Data-to-Viz](https://www.data-to-viz.com){target="_blank"} vorbei. Diese bietet Euch hervorragende Hilfestellungen und liefert gleichzeitig Code-Schnipsel zur praktischen Implementierung.
- In R nutzen wir vor allem die Packages `ggplot2` und `plotly` zur Datenvisualisierung. Das `sf`-Package ermöglicht uns die Arbeit mit Geodaten (z.B. um Karten zu erstellen) - daher werden wir auch kurz darüber sprechen.
## **Quiz**
```{r 10visualisierung}
quiz(caption = NULL,
question("Wofür kann und sollte man Datenvisualisierung nutzen?",
answer("Zur interaktiven Informationsweitergabe.", correct = TRUE),
answer("Um Stories zu untermauern.", correct = TRUE),
answer("Um überfrachtete Graphiken zu präsentieren."),
answer("Um Muster zu erkennen.", correct = TRUE),
correct = "Richtig, die Möglichkeiten der Datensisualisierung sind nahezu unbegrenzt! Jedoch sollten wir immer darauf achten, dass wir die Grafiken so einfach wie möglich halten.",
incorrect = "Leider falsch, versuche es einfach nochmal oder schau im Video nach!",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Was gilt auch für Datenvisualisierungen?",
answer("Function follows form (Funktion folgt Form)."),
answer("Form follows function (Form folgt Funktion).", correct = TRUE),
correct = "Richtig, leider sehen wir häufig Datenvisualisierungen, die zwar toll aussehen, die eigentliche Botschaft aber nicht wirklich vereinfachen! Beim Betrachten bleiben wir dann leider mit vielen Fragezeichen zurück.",
incorrect = "Leider falsch, Form folgt Funktion! Leider sehen wir häufig bunte Datenvisualisierungen, die die eigentliche Botschaft aber nicht wirklich vereinfachen! Beim Betrachten bleiben wir dann leider mit vielen Fragezeichen zurück.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Wie schon in der Sitzung 'Daten verstehen mit R' besprochen, können Boxplots eine nützliche Darstellung sein. Aber warum genau sind sie so nützlich?",
answer("Sie sind leicht zu lesen."),
answer("Sie stellen die fünf Punkte der Verteilung (statistische Kennzahlen) visuell da.", correct = TRUE),
answer("Sie zeigen die genaue Lage der Beobachtungspunkte an."),
correct = "Richtig, sie fassen die fünf Punkte der Verteilung (Minimum, 25%-Quartil, Median, 75%-Quartil, Maximum) zusammen und geben damit einen sehr guten Überblick über die Daten.",
incorrect = "Leider falsch, Boxplots stellen die fünf Punkte der Verteilung visuell dar - sie sind deshalb aber nur gut zu verstehen, wenn man diese auch kennt. Rückschlüsse auf die Verteilung einzelner Beobachtungen sind allerdings nicht möglich.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Warum haben Kreisdiagramme oft einen schlechten Ruf?",
answer("Weil sie altmodisch sind."),
answer("Weil sie nur schwer zu lesen sind."),
answer("Weil sie oft überfrachtet werden.", correct = TRUE),
correct = "Richtig, Kreisdiagramme sollten nur für Variablen mit zwei bis drei Kategorien erstellt werden, z.B. Ja, Nein, NA. Bei mehr Kategorien können wir Verhältnisse nicht mehr richtig abschätzen.",
incorrect = "Leider falsch, Kreisdiagramme sollten nur für Variablen mit zwei bis drei Kategorien erstellt werden, z.B. Ja, Nein, NA. Bei mehr Kategorien können wir Verhältnisse nicht mehr richtig abschätzen.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Wie heißt die erste Empfehlung von From-Data-to-Viz für mehrere geordnete, numerische Variablen? (Tipp: Geht zu data-to-viz.com und schaut dort nach.)",
answer("Boxplots."),
answer("Liniendiagramme."),
answer("Geschichtete Flächendiagramme.", correct = TRUE),
correct = "Richtig, auf Englisch heißen diese stacked area plots.",
incorrect = "Leider falsch, es werden geschichtete Flächendiagramme (engl. stacked area plots) empfohlen.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Wie heißen die drei Schichten einer ggplot-Graphik, die immer enthalten sein müssen?",
answer("data", correct = TRUE),
answer("aes", correct = TRUE),
answer("theme"),
answer("geom_*", correct = TRUE),
answer("labs"),
answer("coord_cartesian"),
correct = "Richtig, an erster Stelle müssen wir den Datensatz (data), Achsenattribute (aes) und Darstellungsform (geom_xxx) definieren - alles andere ist optional und kann später hinzugefügt werden.",
incorrect = "Leider falsch, an erster Stelle müssen wir den Datensatz (data), Achsenattribute (aes) und Darstellungsform (geom_xxx) definieren - alles andere ist optional und kann später hinzugefügt werden.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
)
)
```
# **Interaktive Übung**
<right>
{#id .class width=20% height=60%}
</right>
<br>
In dieser Sitzung werden wir uns vor allem mit dem Package **`ggplot2`** beschäftigen, das ebenfalls im Tidyverse enthalten ist und uns viele Visualisierungsmöglichkeiten bietet. Am Ende wissen wir, wie wir einigermaßen selbstständig Visualisierungen erstellen (wie die in [unserer App](https://correlaid.shinyapps.io/breakfreefromplastic/){target="_blank"}) - oder wo wir nachschauen müssen, wenn wir einmal nicht weiter wissen.
## **Wiederholung: `ggplot2`-Basics**
Erinnert Ihr Euch noch an die [Lektion zu Daten verstehen mit R](https://rlernen.correlaid.org/06_daten-verstehen-mit-r.html){target="_blank"}? In Dieser Session haben wir nämlich schon einmal von dem ggplot2-Package gehört. `ggplot2` orientiert sich an der Philosophie des ["Grammar of Graphics"](https://ggplot2-book.org/introduction#what-is-the-grammar-of-graphics) (daher auch der Name **gg**plot), das uns mit einer grundlegenden Definition einer Visualisierung ausstattet:
> a graphic maps the *data* to the *aesthetic attributes* (colour, shape, size) of *geometric objects* (points, lines, bars)
Wir stellen also unsere Daten als "geometrische Objekte" mit "ästhetischen Eigenschaften" dar. `ggplot2` folgt dabei einer **Lagen- bzw. Schichtlogik**, nach der eine Visualisierung Stück für Stück aufgebaut wird.
Für einen ganz simplen Plot benötigen wir immer:
- `data()` = **Datensatz**
- `aes()` = **"ästhetische Attribute"** (z.B. die x- oder y-Achse)
- `geom_*()` = **geometrische Form**, also die Darstellungsform unserer Daten (z.B. Balkendiagramm, Histogramm, etc.)
**Wichtig**: Die einzelnen Lagen bzw. Schichten werden bei `ggplot2` mit einem **"+" verknüpft**. Und auch wenn das Package selbst `ggplot2` heißt, ist der erste Befehl, wenn wir unsere Visualisierung aufbauen, immer `ggplot()` (ohne die "2").
Eine ganz einfache Visualisierung mit `ggplot2` erfolgt immer über folgendes Prinzip:
```
Daten +
Ästhetische Attribute +
geometrische Formen (z.B. Punkte, Linien, Balken...)
```
Man kann es aber auch komplexer gestalten und erweitern. Jedoch sollte man unbedingt auf die Reihenfolge der Schichten achten, denn diese können einen Unterschied machen:
```
Daten +
Ästhetische Attribute +
geometrische Formen +
Skalen (z.B. Achsenskala (logarithmisch o.ä.) oder Farbskala)+
Koordinatensystem +
Ggf. Gruppierung der Graphen +
Visuelle Anpassung der Darstellungsform ("theme")
```
Wir starten von Anfang an und werden uns Schritt für Schritt steigern! Zunächst einmal benötigen wir natürlich unser Werkzeug: Das Package `ggplot2`.
```{r package_prep_ggplot2, exercise = TRUE}
# install.packages("ggplot2")
library(ggplot2)
```
Alle wichtigen `ggplot2` Befehle findet Ihr in diesem [Schummelzettel](https://github.com/CorrelAid/rlernen_umwelt/blob/main/cheatsheets/07_cheatsheet-ggplot2.pdf){target="_blank"}.
## **Die Basisebene**
Wenn man nur die `ggplot()`-Funktion alleine aufruft, produziert das einen leeren Plot:
```{r ggplot_empty, exercise = TRUE}
ggplot()
```
Dies ist quasi die **Basisebene**, die wir nun nach und nach füllen können. Dafür müssen wir als Erstes festlegen, welche Daten wir verwenden und wie diese dargestellt werden sollen (= `mapping`):
```{r ggplot_axes, exercise = TRUE}
ggplot(data = community, mapping = aes(x = n_volunteers, y = n_pieces))
```
## **Zusatzebene: Grafiktyp**
Die `aes()`-Funktion kontrolliert alle **ästhetischen Zuweisungen**. Wir haben jetzt also schon einmal einen Graphen mit Achsen erstellt, den wir nun füllen müssen. Je nachdem, welche Daten uns vorliegen, kommen dafür verschiedene Grafiktypen infrage, die wir uns gleich auch nochmal anschauen werden. An dieser Stelle entscheiden wir uns für das **Punktdiagramm** als "geometrisches Objekt" (`geom_point()`). Dazu fügen wir mit `+` eine weitere Ebene hinzu:
```{r ggplot_geom, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces)) +
geom_point()
```
So wie sich die Position der Punkte durch `x` und `y` bestimmen lässt, können wir auch ihre Farbe etwas darstellen lassen; z.B. welchem Kontinent eine Beobachtung zugehörig ist. Dazu fügen wir innerhalb von `aes()` ein weiteres "mapping" (`color = continent`) hinzu:
```{r ggplot_color, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent)) +
geom_point()
```
## **Zusatzebene: Information**
Wir sehen schon, dass es hier einige Ausreißer nach oben gibt, was die Teilnehmendenzahl und die gesammelte Menge angeht. Wie gehen wir damit um? Im Grunde gibt es zwei Optionen:
1. Ausschluss der entsprechenden Beobachtungen
2. Auswahl einer passenden Darstellungsform
Da wir unsere Daten vollständig präsentieren wollen, entscheiden wir uns für Option 2 und stellen unsere Daten auf einer logarithmischen Skala dar. Hierfür fügen wir neue Ebenen hinzu: `scale_x_log10()` für eine logarithmische x-Achse, und `scale_y_log10()` für eine logarithmische y-Achse:
*Hinweis: Häufig sind unsere Daten nicht normalverteilt, obwohl das die meisten statistischen Modelle voraussetzen - wir haben darüber bereits einmal kurz in den [Grundlagen der Statistik](https://rlernen.correlaid.org/03_grundlagen-der-statistik.html){target="_blank"} dazu gesprochen. Mithilfe verschiedener Transformationsverfahren (u.a. der Logarithmierung) können wir unsere Daten in eine annähernde Normalverteilung umformen. Anschließende Analysen führen wir dann mit den transformierten Daten durch. Eine kurze Zusammenfassung dazu, findet Ihr auch [hier](https://www.ibm.com/docs/de/cognos-analytics/11.1.0?topic=visualizations-logarithmic-scale){target="_blank"}.*
Und so sehen unsere logarithmierten Daten aus - deutlich übersichtlicher und aussagekräftiger, oder?
```{r ggplot_scale, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent)) +
geom_point() +
scale_x_log10() +
scale_y_log10()
```
Neben der Farbe der Punkte (`color`) gibt es noch zahlreiche weitere Eigenschaften, z.B. ihre Größe (`size`). Diese können wir hier zum Beispiel nutzen, um ebenfalls die Anzahl der Events in unserem Plot darzustellen. Dazu erweitern wir `aes()`:
```{r ggplot_size, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent, size = n_events)) +
geom_point() +
scale_x_log10() +
scale_y_log10()
```
Allerdings könnten jetzt kleinere Datenpunkte von sehr großen verdeckt werden. Dieses Problem können wir mithilfe einer weiteren Eigenschaft der Punkte lösen: Ihrer Deckkraft (`alpha`). Wenn wir einer ästhetischen Eigenschaft einen festen Wert geben wollen, können wir ihn **außerhalb** von `aes()` zuweisen (entweder innerhalb `ggplot()` oder `geom_point()`):
```{r ggplot_alpha, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent, size = n_events)) +
geom_point(alpha = 0.5) +
scale_x_log10() +
scale_y_log10()
```
## **Zusatzebene: Layout**
Das sieht doch schon gut aus! Nun können wir uns dem Feinschliff zuwenden. `ggplot2()` hat mehrere eingebaute **"themes"**, also voreingestellte Layout-Formate, die wir verwenden können. Falls uns der Standard-Look nicht gefällt können wir einfach eine weitere Ebene für das `theme_*` hinzufügen und diesen ändern:
```{r ggplot_themes, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent, size = n_events)) +
geom_point(alpha = 0.5) +
scale_x_log10() +
scale_y_log10() +
theme_minimal()
```
Noch besser - als nächstes sehen wir uns die Achsen an. Die y-Achse ist aktuell aufgrund der Logarithmierung unserer Daten nicht optimal formatiert (wir hätten gern 1,000 statt 1e+03). Damit alles einheitlich ist, bringen wir die x-Achse am besten noch in das selbe Format. Das Format der **Labels** können wir mit Hilfe des `scales`-Packages innerhalb der entsprechenden Ebenen ändern.
*Anmerkung: Das `scales`-Package ist ein Zusatz, das Funktionen enthält, die wir dafür verwenden können, um Achsenbeschriftungen, Farben und andere Merkmale unserer Grafiken anzupassen. Schaut doch gerne noch einmal in die [Dokumentation des Packages](https://scales.r-lib.org/){target="_blank"} rein, wenn Ihr noch mehr dazu wissen möchtet!*
```{r ggplot_axlabels, exercise = TRUE}
ggplot(community, aes(x = n_volunteers, y = n_pieces, color = continent, size = n_events)) +
geom_point(alpha = 0.5) +
scale_x_log10(labels = scales::label_comma()) +
scale_y_log10(labels = scales::label_comma()) +
theme_minimal()
```
## **Zusatzebene: Labels**
Als nächstes möchten wir noch ein paar **Labels** hinzufügen: Einen Titel (& ggf. Untertitel), bessere Achsenbeschriftungen und am besten auch bessere Beschriftungen unserer Eigenschaften in der Legende. Wenn wir anderen Menschen unsere Daten visuell präsentieren wollen, ist dieser Schritt besonders wichtig, denn ohne eine verständliche Beschritftung unserer Grafiken geht ein Großteil der darin enthaltenen Informationen verloren! Wir können für die Labels eine weitere `labs()`-Ebene hinzufügen:
```{r ggplot_labels, exercise = TRUE}
final_plot <- ggplot(community,
aes(x = n_volunteers, y = n_pieces, color = continent, size = n_events)
) +
geom_point(alpha = 0.5) +
scale_x_log10(labels = scales::label_comma()) +
scale_y_log10(labels = scales::label_comma()) +
theme_minimal() +
labs(
title = "Plastiksammeln",
subtitle = "Freiwillige & Events weltweit",
x = "Freiwillige",
y = "Gesammelte Stücke",
size = "Events",
color = "Kontinent"
)
final_plot
```
## **Plot speichern**
Um einen Plot zu speichern, könnt Ihr entweder die entsprechenden Bedienelemente in RStudio's "Plots"-Panel nutzen, oder die `ggsave`-Funktion:
```{r ggplot_saving, exercise = TRUE, eval=FALSE, exercise.setup = "ggplot_labels"}
ggsave(filename = "MeinPlot.png", plot = final_plot)
```
## **Zusatzebene: Facets**
Nehmen wir an, wir wollen den vorherigen Plot nun für alle Kontinente einzeln erstellen. Müssten wir dann nach `continent` filtern, alle Plots einzeln erstellen und dann wieder zusammenstückeln?
Nein, natürlich nicht! `ggplot` kann einen Plot "facettieren", also den selben Plot für unterschiedliche Gruppen erstellen. Dazu müssen wir eine Ebene `facet_wrap()` hinzufügen und ggplot mitteilen, nach welcher Variable es "facettieren" soll (die Syntax: `~variable`):
```{r ggplot_facets, exercise = TRUE, exercise.setup = "ggplot_labels"}
final_plot +
facet_wrap(~continent)
```
Ein Tipp am Rande: Falls sich - wie in diesem Fall - die (x-) Achsenlabels überlappen, lassen sich diese durch etwas interne ggplot-Trickserei innerhalb einer `theme()`-Ebene anwinkeln:
```{r ggplot_facets_axis_text, exercise = TRUE, exercise.setup = "ggplot_labels"}
final_plot +
theme(axis.text.x = element_text(angle = 45)) +
facet_wrap(~continent)
```
Zugegeben: Die Syntax für diese **Nicht-Daten-Komponenten**, die man innerhalb von `theme()` modifizieren kann ist etwas gewöhnungsbedürftig. [Hier](https://ggplot2.tidyverse.org/reference/theme.html){target="_blank"} gibt es allerdings eine gute Einführung in der ggplot2-Dokumentation.
---
# **Zusätzliche Darstellungsformen**
In unserem Beispiel haben wir uns das Punktdiagramm als eine Darstellungsform angeschaut, doch natürlich gibt es noch viel mehr Möglichkeiten um Daten graphisch zu veranschaulichen - einige kennt Ihr bereits!
* **Balkendiagramm:** `geom_col()` & `geom_bar()`:
```{r ggplot_geoms_col, exercise = TRUE}
community %>%
dplyr::group_by(continent) %>%
dplyr::summarise(events = sum(n_events)) %>%
ggplot(aes(x = continent, y = events, fill = continent)) + # fill = Füllfarbe!
geom_col()
```
* **Boxplots** & **Violin-Plots**<br>
*Wird häufig zur Darstellung von Verteilungen verwendet.*
```{r ggplot_geoms_boxplot, exercise = TRUE}
ggplot(community, aes(x = continent, y = n_pieces, fill = continent)) +
geom_boxplot() +
scale_y_log10(labels = scales::comma_format())
```
* **Histogramme:**
```{r ggplot_geoms_histogram, exercise = TRUE}
ggplot(community, aes(x = n_events)) +
geom_histogram()
```
An dieser Stelle können wir natürlich nur einen kleinen Teil aller graphischen Darstellungsformen betrachten. Ein weiteres häufig genutzes "geom" ist `geom_line()`, ein **Liniendiagramm**, das sich vor allem für die Darstellung von Zeitreihen eignet. Wir haben es bereits in der Session [Grundlagen der Statistik](https://rlernen.correlaid.org/03_grundlagen-der-statistik.html){target="_blank"} im Rahmen der verschiedenen Pressemitteilungen kennengelernt - vielleicht erinnert Ihr Euch. Die [R Graph Gallery](https://r-graph-gallery.com/ggplot2-package.html){target="_blank"} bietet Euch darüberhinaus noch einen umfassenden Einblick in alle möglichen Graphiken - Codes inklusive!
## **Kombinierte Darstellungsformen**
Die Visualierungsmöglichkeiten in R sind mithilfe des `ggplot2`-Packages nahezu unbegrenzt, da sich auch mehrere Darstellungsformen miteinander kombinieren lassen. Natürlich müssen wir dabei immer darauf achten, dass eine solche Kombination auch Sinn ergibt und unsere Grafik weiterhin übersichtlich bleibt. Hier ein Beispiel:
```{r ggplot_geoms_combining, exercise = TRUE}
ggplot(community, aes(x = continent, y = n_pieces, fill = continent)) +
geom_violin(alpha = 0.25) +
geom_boxplot() +
geom_point(alpha = 0.25, position = position_jitter(width = 0.2)) +
# ^ jitter = "zittern", also zu einer Punktewolke auseinander"zittern"
scale_y_log10(labels = scales::comma_format())
```
<h1>**Exkurse**</h1>
---
<details>
<summary><h2><b>Exkurs 1: Karten</b></h2></summary>
<br>
Mit Geodaten haben wir uns bereits im Zuge des Kapitels ["Datenimport - Exkurs: Geo"](https://rlernen.correlaid.org/05_0_datenimport-exkurs-geodaten.html){target="_blank"} beschäftigt. Daran setzen wir an dieser Stelle wieder an. Das [`sf`-Package](https://r-spatial.github.io/sf/){target="_blank"} verwenden wir, um erfolgreich mit Geodaten zu arbeiten und z.B. Karten zu erstellen:
```{r ggplot_maps_setup, exercise = TRUE}
library(sf)
library(dplyr)
```
"sf" steht für "Simple Features", einen Standard, um geografische Merkmale darzustellen. Als erstes besorgen wir uns eine Weltkarte (hier als "Shapefile" (.shp), ein geläufiges Format für diese Art von Daten):
```{r ggplot_maps_data, exercise = TRUE, exercise.setup = "ggplot_maps_setup"}
world <- sf::st_read(here::here('daten/geospatial/ne_50m_admin_0_countries.shp'), quiet = TRUE)
world <- world %>%
dplyr::filter(SOVEREIGNT != "Antarctica") %>%
# ^ werden wir wohl nicht brauchen & nimmt viel Platz ein...
dplyr::select("countrycode" = ISO_A2, "country" = SOVEREIGNT)
tibble(world)
```
In diesem Datensatz mit "simple features" haben wir neben dem `countrycode` noch eine weitere Spalte, `geometry`, in der die **Form jedes Landes** enthalten ist. Nun müssen wir beide Datensätze anhand der gemeinsamen Variable **`countrycode`** zusammenfügen:
```{r ggplot_maps_merging, exercise = TRUE, exercise.setup = "ggplot_maps_data"}
map <- world %>%
dplyr::left_join(community %>% dplyr::select(-country), by = "countrycode") %>%
dplyr::select(country, countrycode, dplyr::starts_with("n_")) %>%
# NA in community = keine Events, kein Plastik gesammelt:
dplyr::mutate(dplyr::across(dplyr::starts_with("n_"), function(x) tidyr::replace_na(x, 0)))
```
Für ggplot2 gibt es ein eigenes `geom`, um nun aus diesen Daten ganz einfach eine Karte zu erstellen: **`geom_sf()`**. Die anderen `aes()`, wie zum Beispiel `fill` (Füllfarbe) funktionieren wie gehabt:
```{r ggplot_maps_plot, exercise = TRUE, exercise.setup = "ggplot_maps_merging"}
worldmap <- ggplot(map, aes(fill = n_events)) +
geom_sf() +
scale_fill_gradient(low = "white", high = "darkgreen") +
theme_void() +
labs(title = "Number of events across the world", fill = "Events")
worldmap
```
Wer sich etwas mit Geodaten auskennt, kann auch ausgefallenere Dinge ändern, z.B. die Projektion:
```{r ggplot_maps_projection, exercise = TRUE, exercise.setup = "ggplot_maps_plot"}
worldmap +
coord_sf(crs = "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs ")
```
</details>
---
---
<details>
<summary><h2><b>Exkurs 2: Interaktive Plots mit plotly</b></h2></summary>
<br>
In R lassen sich mithilfe des **`plotly`**-Packages auch interaktive Grafiken erstellen. Das Package bietet uns neue Möglichkeiten, um dynamische und flexible Visualisierungen als HTML-Dateien zu erstellen und abzuspeichern. Somit lassen sie sich problemlos auf Websites einfügen oder teilen. `plotly` unterstützt verschiedene Diagrammtypen (z.B. Linien-, Balken- und Streudigramme) und ermöglicht u.a. ebenfalls die Erstellung komplexerer 3D-Modelle. Das Package lässt sich sehr gut mit dem `gglot2`-Package kombinieren und ist daher besonders praktisch, wenn wir bereits bestehende Visualisierungen bearbeiten wollen. Mehr dazu findet Ihr [hier](https://plotly-r.com/){target="_blank"}.
Zunächst laden wir also wie gewohnt das neue Package:
```{r ggplot_plotly_setup, exercise = TRUE, exercise.setup = "ggplot_maps_plot"}
library(plotly)
```
Die einfachste Variante, einen interaktiven Graphen zu erstellen, ist die Anwendung der **`ggplotly()`-Funktion** auf einen bestehenden ggplot, um diesen in einen interaktiven Plot zu konvertieren.
```{r ggplot_plotly_ggplotly, exercise = TRUE, exercise.setup = "ggplot_plotly_setup"}
worldmap %>%
plotly::ggplotly()
```
Schnell merken wir den Unterschied: Im Vergleich zu unserer vorherigen Graphik können wir nun mit dem Cursor über unsere Karte navigieren, mithilfe der Toolleiste die Datei downloaden oder zoomen. Unsere ursprünglich komplexen Daten werden trotzdem noch überischtlich dargestellt und lassen sich somit viel einfacher Erkunden.
`ggplotly()` versucht dabei möglichst alle Elemente weiterzureichen. Wenn wir zum Beispiel weitere `aes()` setzen, werden diese - nach Möglichkeit - auch von plotly berücksichtigt. Dafür müssen wir allerdings zunächst einmal die Labels festlegen und diese mithilfe der Funktion zuweisen. Die Logik ist hierbei (noch) analog zum ggplot2-Package:
```{r ggplot_plotly_labels, exercise = TRUE, exercise.setup = "ggplot_plotly_setup"}
with_labels <- map %>%
dplyr::rename("Land" = country, "Events" = n_events) %>%
# "Label" mit dem Namen der Länder hinzufügen:
ggplot(aes(label = Land, fill = Events)) +
geom_sf() +
scale_fill_gradient(low = "white", high = "darkgreen") +
theme_void() +
labs(title = "Events weltweit", fill = "Events")
with_labels_plotly <- with_labels %>%
# In `ggplotly()` können wir die beim Überfahren mit der Maus
# angezeigten "Tooltips" anpassen:
plotly::ggplotly(tooltip = c("Land", "Events"))
with_labels_plotly
```
Manchmal lassen sich allerdings **nicht** alle Elemente aus einem ggplot nahtlos in einen plotly-Plot übersetzen. Plotly hat nämlich auch eine eigene Syntax:
```{r ggplot_plotly_plotly, exercise = TRUE, exercise.setup = "ggplot_plotly_setup"}
community %>%
plotly::plot_ly(
# Als erstes ganz klassisch das, was bei ggplot2 die
# `aes()` wären:
x = ~n_volunteers,
y = ~n_pieces,
color = ~continent,
size = ~n_events,
text = ~country,
# Dann den "type" - quasi die `geom_*()`:
type = "scatter",
mode = "markers",
# Wir können den beim Überfahren angezeigten Text auch
# aus HTML zusammenstückeln:
hovertemplate = paste(
"<b>%{text}</b><br><br>",
"Stücke: %{y:.0f}<br>",
"Freiwillige: %{x:.0f}<br>"
)
) %>%
# Viele visuelle Elemente werden separat innerhalb der
# `layout()`-Funktion kontrolliert:
plotly::layout(
# Plotly erlaubt an vielen Stellen HTML-Trickserei:
title = "<b>Plastiksammlung Weltweit</b><br><sup>Teilnehmer & gesammelte Stücke</sup>",
xaxis = list(title = list(text = "Freiwillige"), type = "log"),
yaxis = list(title = list(text = "Stücke"), type = "log"),
legend=list(title = list(text = "<b>Kontinent</b>"))
)
```
Die plotly-Plots könnt Ihr als HTML-Datei speichern und dann im Browser öffnen.<br> **Achtung:** Im Plot wird der gesamte Datensatz verwendet (und nicht nur die verwendeten Variablen), sodass die exportierte HTML-Datei ggf. sehr groß wird. **Selektiert** idealerweise vor dem Erstellen der plotly-Visualisierung Euren Datensatz, sodass er nur die Variablen enthält, die Ihr benötigt - dann kann die HTML-Datei vielleicht auch wieder per Mail versendet werden, weil sie eine geringere Dateigröße hat und Ihr versendet nicht aus Versehen personenbezogene Daten etc.
```{r ggplot_plotly_save, exercise = TRUE, exercise.setup = "ggplot_plotly_labels"}
htmlwidgets::saveWidget(with_labels_plotly, 'events-weltweit.html')
```
</details>
---
# **Und jetzt Ihr! (optional)**
Es ist Zeit, das Gelernte auszuprobieren! In Session 07 ["Datentransformation Basics"](https://rlernen.correlaid.org/07_datentransformation.html){target="_blank"} haben wir eine **"Top 10 der Müllproduzenten"** aus dem Datensatz gefiltert. Versucht einmal, diese Rangliste in ein **Balkendiagramm geom_bar()** zu übertragen. Ihr könnt Euch dabei an den Codes dieser Session orientieren. In unserer [Beispielapplikation](https://correlaid.shinyapps.io/breakfreefromplastic/){target="_blank"} könnt Ihr die Visualisierung live sehen und nachbauen. Als Layoutoptionen haben wir die Farbe `#4E97AC` und `theme_minimal()` genutzt. Experimentiert gerne mit weiteren Gestaltungsoptionen. Wie würden wir beispielsweise Beschriftungen für die Datenpunkte hinzufügen?
Probiert das zunächst einmal selbst. Solltet Ihr dabei Probleme haben, könnt Ihr allerdings auch die **R-Datei: 09_datenvisualisierung-uebung.R** im [Übungsordner](https://download-directory.github.io/?url=https://github.com/CorrelAid/rlernen_umwelt/tree/main/uebungen){target="_blank"} verwenden!
---
# **Zusätzliche Ressourcen**
- Dataquest bietet auch einen [Kurs zu Datenvisualisierungen in R](https://app.dataquest.io/course/r-data-viz){target="_blank"} an
- [Schummelzettel zu `ggplot2`](https://github.com/CorrelAid/rlernen_umwelt/blob/main/cheatsheets/07_cheatsheet-ggplot2.pdf){target="_blank"}
- Mehr dazu, wie ihr ggplot-Grafiken mit [`plotly` interaktiv werden lasst](https://plotly.com/ggplot2/getting-started/)
- [Schummelzettel zu `plotly`](https://github.com/CorrelAid/rlernen_umwelt/blob/main/cheatsheets/09_cheatsheet-plotly.pdf){target="_blank"}
- [RStudios Tutorial zu interaktiven Karten mit leaflet (engl.)](https://rstudio.github.io/leaflet/){target="_blank"}
- [Data to Viz](https://www.data-to-viz.com/){target="_blank"}
- [R Graph Gallery ](https://www.r-graph-gallery.com/){target="_blank"}
- Online-Version von ["ggplot2: Elegant Graphics for Data Analysis"](https://ggplot2-book.org/index.html){target="_blank"} von Hadley Wickham (engl.)
- Einblicke in den [Datenjournalismus (engl.)](https://www.mzes.uni-mannheim.de/socialsciencedatalab/article/telling-stories-with-data/){target="_blank"}
- [Visual Inference with R (engl.)](https://www.mzes.uni-mannheim.de/socialsciencedatalab/article/visinference/){target="_blank"} (engl.)
- [Datenvisualisierung (Wieso, warum und wie?)](https://www.skala-campus.org/artikel/tipps-daten-visualisieren/146){target="_blank"}
<a class="btn btn-primary btn-back-to-main" href=`r params$links$end_session`>Session beenden</a>