forked from CorrelAid/lernplattform
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path07_datenvisualisierung.Rmd
More file actions
483 lines (397 loc) · 35.5 KB
/
07_datenvisualisierung.Rmd
File metadata and controls
483 lines (397 loc) · 35.5 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
## **Datenvisualisierung**
[](https://creativecommons.org/licenses/by/4.0/deed.de)
*"Datenvisualisierung" von Cosima Meyer in "R Lernen - der Datenkurs von und für die Zivilgesellschaft" von CorrelAid e.V. Lizensiert unter [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/deed.de).*

### **Kernaussagen**
- Visualisierungen **vereinfachen und beschleunigen** die Vermittlung von (komplexen) Inhalten, weil Menschen visuelle Zusammenhänge oft schneller begreifen können als Text
- Sie erlauben uns in Daten **Muster** zu erkennen (z.B. zur Verteilung von und zu Beziehungen zwischen Variablen)
- Auch **Fehler und Ausreißer** in den Daten können mit ihnen schnell identifiziert werden
- Mit der Möglichkeit der interaktiven Gestaltung erlauben sie uns, **spannende Narrative** zu entwickeln (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:
- Der **Art der Variablen** (kontinuierlich oder diskret)
- Der **Anzahl an Variablen**, die visualisiert werden sollen
- Der **Botschaft**, die vermittelt werden soll
- Die Webseite [From-Data-to-Viz](https://www.data-to-viz.com){target="_blank"} bietet einen hervorragenden **Ausgangspunkt**, um sich für eine Visualisierung zu entscheiden und liefert auch gleichzeitig Code-Schnipsel zur praktischen Implementierung
- Wir schauen uns in dieser Lektion gemeinsam die R-Packages `ggplot2` und `leaflet` an
### **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!",
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 - aber von einer Vereinfachung der Botschaft kann keine Rede sein. Beim Betrachten bleiben wir dann leider mit vielen Fragezeichen zurück.",
incorrect = "Leider falsch: Form folgt Funktion! Leider sehen wir häufig Datenvisualisierungen, die zwar toll aussehen - aber von einer Vereinfachung der Botschaft kann keine Rede sein. Beim Betrachten bleiben wir dann leider mit vielen Fragezeichen zurück.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Wie schon in Sitzung 5 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 Daten.",
incorrect = "Leider falsch: Boxplots stellen die fünf Punkte der Verteilung visuell dar, sind deshalb aber nur gut zu verstehen, wenn man diese auch kennt. Wie einzelne Beobachtungen liegen, kann man nicht erkennen.",
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!",
incorrect = "Leider falsch: ggplots benötigen zumindest Daten (data), Variablen (aes) und eine Darstellungsform (geom_xxx)",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
)
)
```
### **Interaktive Übung**
<right>
{#id .class width=20% height=60%}
</right>
<br>
In dieser Sitzung lernt Ihr zunächst verschiedene Visualisierungsformen- und Möglichkeiten mit `ggplot2` kennen. Ziel ist es, dass Ihr hinterher die Visualisierungen in unserem Report und in unserer Shiny Web App erstellen könnt [(zur App)](https://correlaid.shinyapps.io/breakfreefromplastic/){target="_blank"}.
#### Wiederholung: `ggplot2`-Basics
Erinnert Ihr Euch noch an die [fünfte Sitzung](https://correlaid.shinyapps.io/lernplattform/#section-daten-verstehen-mit-r)?
- `ggplot2` folgt einer **Lagen- bzw. Schichtlogik**, d.h. wir bauen unsere Visualisierung nach und nach auf
- Für einen ganz simplen Plot benötigen wir immer:
- `data` (der **Datensatz**)
- `aes()` (die **"ästhetischen Attribute"** wie beispielsweise die x- oder y-Achse)
- `geom_*()` (die **geometrische Form**, d.h. mit welcher Visualisierungsform Eure Daten dargestellt werden sollen z.B. in einem Balkendiagramm oder Histogramm)
- **Wichtig**: Die einzelne Bestandteile werden bei `ggplot2` mit einem **"+" verknüpft**. Und auch wenn das Package selbst `ggplot2` heißt, ist der erste Befehl, wenn Ihr Eure Visualisierung aufbaut, immer `ggplot()` (ohne die "2").
Die zwei "g" im Packagenamen `ggplot2` stehen für "**g**rammar of **g**raphics". `ggplot2` folgt damit einer "Lagenlogik" oder "Schichtlogik", nach der eine Visualisierung Stück für Stück aufgebaut wird. Eine ganz einfache Visualisierung mit `ggplot2` erfolgt immer über folgendes Prinzip:
```
Daten +
Ästhetische Attribute +
geometrische Formen (z.B. ob es ein Liniendiagramm oder Balkendiagramm ist)
```
Man kann es aber auch komplexer gestalten und erweitern:
```
Daten +
Ästhetische Attribute +
geometrische Formen (z.B. ob es ein Liniendiagramm oder Balkendiagramm ist)
Skalen +
Koordinatensystem +
Ggf. Gruppierung der Graphen +
Visuelle Anpassung der Darstellungsform (Thema)
```
Für diese Lektion benötigt Ihr also `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/lernplattform/blob/main/cheatsheets/07_cheatsheet-ggplot2.pdf){target="_blank"}.
#### Inspiration suchen
Wir orientieren uns an einer Euch bereits bekannten Graphik:
```{r boxplot_plastik_viz, echo = FALSE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Standardabweichung
labs(
title = "Die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") + # Ausblenden der Legende
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) # Anwendung der BFFP-Farben
```
#### Initialisierung
Im ersten Schritt bauen wir diese Graphik Schritt-für-Schritt nach. Wir beginnen mit dem Grundgerüst einer `ggplot`-Graphik: dem **Erstellen eines `ggplot`-Objekts und der Definition von ästhetischen Attributen**. Das sind die Variablen bzw. Spalten, die auf der x-und y-Achse dargestellt werden sollen. Was produziert dieser Code? Was passiert, wenn Ihr die Variablen vertauscht?
```{r grahik1, exercise=TRUE}
# Erstellung eines leeren Plots
ggplot2::ggplot(data = community, aes(x = continent, y = n_volunteers)) # Initialisierung des Plots mit Variablen
```
#### Einfügen der Visualisierungsform
`ggplot2` bietet eine fantastische Vielzahl an Visualisierungsmöglichkeiten! Die bekanntesten (und meist genutzten) sind:
- `geom_point()`: eine Punktewolke
- `geom_beeswarm()`: eine Punktewolke, in der jedoch die einzelnen Punkte zufällig versetzt sind (das hilft uns mehr zu erkennen als es bei einer klassischen Punktewolke möglich wäre)
- `geom_col()`: Balkendiagramm
- `geom_line()`: ein Liniendiagramm (vor allem bei Zeitreihendaten sinnvoll, d.h. Daten, die z.B. den Verlauf über mehrere Zeitpunkte darstellen)
- `geom_histogramm()`: Histogramm (Verteilungsdiagramm)
- `geom_boxplot()`: Boxplot
Das Schöne an der `ggplot2` Logik ist, dass man mit wenigen Handgriffen Visualisierungstypen austauschen kann und so schnell eine vollkommen andere Visualisierung bekommt.
Nun fügen wir dem Plot die **Datenpunkte** hinzu, um eine erste Punktewolke (hier: Beeswarmplot) zu erstellen. Diese Codezeile unterscheidet sich je nach gewählter Visualisierungsform.
```{r geom-point, exercise=TRUE}
ggplot2::ggplot(data = community, aes(x = continent, y = n_volunteers)) +
geom_beeswarm() # Hinzufügen der Datenpunkte (Beeswarmplot)
```
Wie bereits erwähnt kann man in der `ggplot2`-Logik Graphen aufeinander aufbauen. Probieren wir das doch einmal aus - fügt hier den Boxplot hinzu:
```{r geom-point1, exercise = TRUE}
ggplot2::ggplot(data = community, aes(x = continent, y = n_volunteers)) +
geom_beeswarm() # Hinzufügen der Datenpunkte (Beeswarmplot)
# Hier Euer Code
```
```{r geom-point1-solution}
ggplot2::ggplot(data = community, aes(x = continent, y = n_volunteers)) +
geom_beeswarm() + # Hinzufügen der Datenpunkte (Beeswarmplot)
geom_boxplot() # Hinzufügen des Boxplots
```
```{r geom-point1-check}
gradethis::grade_this_code()
```
#### Layoutoptionen
Mit **Layoutoptionen** schaffen wir mehr Übersichtlichkeit. Mit **`alpha = Wert`** ( zwischen 0 und 1) werden die Punkte etwas transparenter, mit **`size= Wert`** (Wert zwischen 0 und +∞) werden die Punkte etwas größer und so auch einzeln besser sichtbar.
```{r geom-point2,exercise=TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5) + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) # Hinzufügen des Boxplots
```
#### Achsenbegrenzungen
Auch in Visualisierungen können wir **Extremwerte** exkludieren. Der Ausschluss von Werten sollte immer gut durchdacht und begründet sein. Es gibt hier leider oft keine "Blaupause", der man folgen kann, sondern es handelt sich oft um Einzelfallentscheidungen. Eine Möglichkeit, um zum Beispiel einen logisch sinnvoll Werterahmen für das Koordinatensystem zu wählen, bilden statistische Kennzahlen wie Mittelwert und Median (auch multipliziert mit einem Faktor und der Standardabweichung), Varianz oder dem Interquartilsabstand. So bleiben Eure Achsen reaktiv, wenn sich die zugrundeliegenden Daten ändern. <br>
*Hinweis: Nicht immer ist der Ausschluss von Extremwerten sinnvoll. Gerade bei der visuellen Exploration der Daten ist es sinnvoll sie zunächst zu inkludieren, da man sich dann bereits Gedanken über die Auswirkungen auf statistische Kennzahlen und Teststatistik machen kann.*
```{r geom-point3,exercise=TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5) + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) # Festlegung der Achsenlänge der y-Achse abhängig von Median und IQR
```
#### Farben
`ggplot2` erlaubt es Euch Farben für Eure Datenpunkte festzulegen. Das kann sehr sinnvoll sein, wenn Ihr **zusätzliche Informationen** übermitteln möchtet, aber auch einfach eine ästhetische Entscheidung sein.
Die Argumente dafür heißen `color` und `fill`:
- `color` erlaubt Euch die Punkte einer Punktewolke zu färben
- `fill` wird zusätzlich notwendig, wenn Ihr größere Flächen (wie beispielsweise in einem Histogramm oder einem Balkendigramm färben möchtet)
Wenn Ihr Euch unsicher seid, welches Argument Ihr benötigt, könnt Ihr auch einfach ausprobieren und gegebenenfalls `color` gegen `fill` austauschen. Ihr habt zwei Möglichkeiten:
**Auswahl einer Farbe** <br>
Um ein **einzelne Farbe** für Eure Graphik festzulegen, könnt Ihr diese innerhalb des `geom_*`-Arguments definieren. `color` und `fill` akzeptieren als Argumente **Hexcodes** (`#...`) und vordefinierte, **ausgeschriebene Farben** wie `"darkgrey"`.<br>
*Tipp: Hexcodes beginnen mit `#` mit einer folgenden Zahlen- und Buchstabenkombination. Ihr könnt sie in der Regel Eurem Corporate Design Booklet entnehmen, über einen "Colorpicker" ablesen oder Euch bei [colorbrewer2.org](https://colorbrewer2.org/#type=sequential&scheme=BuGn&n=3){target="_blank"} inspirieren lassen. Die Seite bietet euch verschiedene Optionen, um auch kopier-, druck- oder farbenblindfreundliche Farben auszuwählen. Vordefinierte Farben findet Ihr als Übersicht [hier](http://sape.inf.usi.ch/sites/default/files/ggplot2-colour-names.png){target="_blank"}.*
**Auswahl mehrerer Farben (auf Basis einer Variable)** <br>
Wollt Ihr die Farben analog zu einer Variable im Datensatz ändern (die entweder schon in der Graphik enthalten ist oder zusätzlich hinzugefügt werden soll), müsst Ihr die Farbe **innerhalb des `aes()` Arguments** bestimmen (`color = variable` oder `fill = variable`).
Wir nehmen dazu wieder unsere vorbereiteten Daten und den Plot von oben. Die Punkte haben wir bereits mit `color = "darkgrey"` eingefärbt. Verändert den Code so, dass jeder Kontinent eine andere Farbe hat. <br>
*Tipp: Achtet auf den richtigen Argumentnamen und die richtige Platzierung!*
```{r boxplot_farbe, exercise = TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) # Festlegung der Achsenlänge der y-Achse abhängig von Median und IQR
```
```{r boxplot_farbe-solution}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) # Festlegung der Achsenlänge der y-Achse abhängig von Median und IQR
```
```{r boxplot_farbe-check}
gradethis::grade_this_code()
```
Wenn wir nun in `ggplot2` die Farben für die Einfärbung auf Basis einer Variable manuell ersetzen möchten, nehmen wir den Befehl `scale_fill_manual()` oder `scale_color_manual()`. Da wir die Farben in `aes()` über **`fill`** festlegen, verwenden wir hier `scale_fill_manual()` und fügen dort einen Vektor aus Farben der "Break Free From Plastiks"-Bewegung ein. Lasst den folgenden Code laufen und schaut, wie sich das Ergebnis verändert:
```{r plot_colorscale, exercise=TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und IQR
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) # Anwendung der BFFP-Farben
```
Tolle, **vordefinierte Farbpaletten** findet Ihr hier (hinter den Paketnamen verbergen sich auch Links zu den jeweiligen Webseiten):
- [`ggplot2`](https://www.datanovia.com/en/wp-content/uploads/dn-tutorials/ggplot2/figures/030-ggplot-colors-rcolorbrewer-palettes-colorblind-friendly-1.png){target="_blank"}
- [`wesanderson`](https://github.com/karthik/wesanderson){target="_blank"}
- [`fishualize`](https://nschiett.github.io/fishualize/index.html){target="_blank"}
- [`ghibli`](https://ewenme.github.io/ghibli/index.html){target="_blank"}
- [`rijkspalette`](https://vankesteren.github.io/rijkspalette/){target="_blank"}
- oder aber auch [colorbrewer](https://colorbrewer2.org/#type=sequential&scheme=BuGn&n=3){target="_blank"}, mit dem Ihr nach verschiedenen Kriterien (z.B. kopier- oder farbenblindfreundlich) Eure eigenen Farbpaletten zusammenstellen könnt
#### Anmerkungen
**Anmerkungen** sind ganz wesentliche Bestandteile einer Graphik. Neben Titel, Achsenbeschriftung wäre hier auch ein Hinweis auf die Datenquelle sowie die nichtdargestellte Beobachtung sinnvoll. Dies lässt sich alles über **`labs()`** in die Graphik einfügen. Mit **"`\n`"** könnt Ihr händisch Zeilenumbrüche einfügen und mit `glue::glue()` einzelne Textbausteine "zusammenkleben". Wir blenden zudem die **Legende** aus.
```{r plot_beschriftung, exercise = TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Standardabweichung
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) + # Anwendung der BFFP-Farben
labs(
title = "Die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme(legend.position="none") # Ausblenden der Legende
```
#### Themes
Mit **`theme_()`** geben wir unserem Plot-Layout den letzten Schliff: Hier entscheiden wir uns für `theme_minimal()`. Da wir auch hier wieder in einer Lagenlogik vorgehen, setzen wir erst das Thema `theme_minimal()` fest, um dann in einem zweiten Schritt die Standardeinstellungen dieses Themas zu überschreiben und mit `theme()` die Legende auszublenden:
```{r plot_theme, exercise=TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Standardabweichung
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) + # Anwendung der BFFP-Farben
labs(
title = "Die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") # Ausblenden der Legende
```
Alle anderen Themes von `ggplot2` findet Ihr unter diesem [Link](https://ggplot2.tidyverse.org/reference/ggtheme.html){target="_blank"}. Man kann dieses Repertoire durch weitere Packages wie beispielweise `ggthemes` ergänzen und so auch eine Visualisierung im Economist-Stil erzeugen (für mehr Optionen klickt [hier](https://yutannihilation.github.io/allYourFigureAreBelongToUs/ggthemes/){target="_blank"})!
Und tadaa -- das ist der Plot, den wir erstellen wollten! Herzlichen Glückwunsch - das sieht klasse aus! `ggplot2` ist ein sehr mächtiges Tool mit **vielen Stellschrauben**. Sobald Ihr die Grundlogik des Aufbaus verstanden habt, ist es eigentlich ganz leicht Codebausteine wiederzuverwenden. Probiert hier doch mal dieselbe Graphik für die Anzahl an Freiwilligen zu erstellen:
```{r plot_uebung, exercise = TRUE}
# Hier Euer Code
```
```{r plot_uebung-solution}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_volunteers, fill = continent)) + # Initialisierung des ggplots mit Variablen
geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_volunteers) + 2 * IQR(community$n_volunteers))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Standardabweichung
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) + # Anwendung der BFFP-Farben
labs(
title = "Die Mobilisierung von Freiwilligen durch 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl Freiwilliger",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") # Ausblenden der Legende
```
```{r plot_uebung-check}
gradethis::grade_this_code()
```
#### Facets
Wie Ihr auf dem [Schummelzettel](https://github.com/CorrelAid/lernplattform/blob/main/cheatsheets/07_cheatsheet-ggplot2.pdf){target="_blank"} seht, bietet `ggplot2` noch viel mehr! Mit dem Befehl `facet_wrap()` sprecht Ihr über eine Tilde (`~`) die Spalte an, über die Ihr gruppieren möchtet. Bei uns ist das `continent`, d.h. unser Befehl sieht so aus: `facet_wrap(~continent)`. Diesen Befehl könnt Ihr wie gehabt durch ein `+` verknüpfen.
Im nachfolgenden Code Chunk könnt Ihr es selbst ausprobieren. Wir haben hier Histogramme, also die Darstellungen der Verteilung von Freiwilligen gewählt. Es wäre hier sehr praktisch, wenn man es nach Kontinent darstellen könnte. Dabei hilft und `facet_wrap()` mit dem Ihr die Anzahl der Freiwilligen nach Kontinent (`continent`) gruppieren könnt.
```{r geom_histogram_facet, exercise = TRUE}
ggplot2::ggplot(data = community, aes(x = n_volunteers)) +
geom_histogram()
# Hier Euer Code
```
```{r geom_histogram_facet-solution}
ggplot2::ggplot(data = community, aes(x = n_volunteers)) +
geom_histogram() +
facet_wrap(~continent)
```
```{r geom_histogram_facet-check}
gradethis::grade_this_code()
```
#### Visualisierungen speichern
Im letzten Schritt lernen wir, wie Ihr Eure erstellen Graphen abspeichert! Dazu liefert das Package `ggplot2` eine Funktion, die es ganz leicht macht: `ggplot2::ggsave`.
Ihr ruft dazu `ggplot2::ggsave` auf und definiert den Dateinamen (`filename`). Ihr könnt beim Dateinamen auch den Pfad mit angeben. Solltet Ihr keinen Pfad angeben wird die Datei automatisch auf der Ebene gespeichert, auf der Eure `.R`-Datei liegt. Ihr habt außerdem die Möglichkeit explizit anzugeben, welche Visualisierung Ihr speichern möchtet (standardmäßig sollte das auch die Praxis sein, da man so mögliche Fehler verhindert. Als Standardeinstellung speichert R nämlich die letzte Visualisierung, die Ihr generiert habt.)
In der Praxis sieht der Ablauf dann zum Beispiel so aus:
```{r ggsave_example, eval = FALSE, exercise=TRUE}
# Wir erstellen unseren Plot mit `ggplot2` und speichern ihn in einem Objekt (`histogram_plot`)
# über den assignment operator (`<-`)
histogram_plot <-
ggplot2::ggplot(data = community, aes(x = n_volunteers)) +
geom_histogram()
# Im nächsten Schritt rufen wir das Objekt (`histogram_plot`) in der `ggplot2::ggsave` Funktion auf
# und speichern es auf unserem Pfad
ggplot2::ggsave(filename = "euer_pfad/euer_plot.png", plot = histogram_plot) # Mit explizitem Aufruf der Abbildung
# Alternativen
ggplot2::ggsave(filename = "euer_plot.png") # Ohne Pfad
ggplot2::ggsave(filename = "euer_pfad/euer_plot.png") # Mit Pfad
```
Dieser Befehl erlaubt es Euch, statische Visualisierungen zu speichern. Für interaktive Visualisierungen, wie beispielsweise die durch `leaflet` oder `echarts4r` erstellten Karten, bieten sich andere Formate wie `.html` (über Rmds) oder aber auch eine ShinyApp an -- mehr dazu erfahrt Ihr am Ende des Kurses!
### **Exkurs**: Für das schnelle, visuelle Ausprobieren - `esquisse`
Ein Grundverständnis für die Logik von `ggplot2` ist immer sinnvoll - aber was, wenn ihr mal "schnell" etwas ausprobieren wollt und es in `ggplot2` einfach nicht klappt? Dann gibt es `esquisse`! `esquisse` erlaubt es euch, direkt einen Datensatz anzusprechen und per Klick die Darstellungsmöglichkeiten auszuwählen. Das Schöne an `esquisse` ist, dass man den `ggplot2` Code dann auch direkt kopieren kann und in das R-Skript einfügen kann - so geht nichts verloren und man kann alles replizieren. Wie das funktioniert sehr Ihr hier im Clip. Dort zeige ich Euch, wie man die Daten lädt, einzelne Variablen auswählt, den Plot-Typ dann bestimmt und letztendlich den `ggplot2`-Code in Euer R-Skript kopiert.
<center>
{#id .class width=70% height=70%}
</center>
### **Exkurs**: Karten mit `leaflet`
> Um die Ergebnisse des Codes sehen zu können, müsst Ihr den Code in Eurem lokalen RStudio/R ausführen.
Ihr habt bereits gelernt, wie man **geographische Daten** importiert. Wir fügen die sogenannten Polygone unserem `community`-Datensatz an und fügen drei Spalten ein, die uns später bei den Labels hilft (ein toller Trick, den Ihr Euch für andere Visualisierungsprojekte merken solltet).
```{r kartendaten, exercise = TRUE}
# Einlesen des globalen Shapefiles (geometrischen Datensatzes, erkennbar an .shp) über sf::st_read()
polygons_welt <- sf::st_read(here::here('daten/geospatial/ne_50m_admin_0_countries.shp'))
# Kartendaten vorbereiten
karten_daten <- community %>%
# Wir kodieren hier den Ländercode mit Hilfe der `countrycode`Bibliothek
dplyr::mutate(countrycode = countrycode(country, "country.name", "iso2c")) %>%
# Geometrie anfügen
dplyr::left_join(polygons_welt, by = c("countrycode" = "ISO_A2")) %>%
# Variablen für Singular / Plural Formulierung
dplyr::mutate(word_n_events = if_else(n_events == 1, "Event", "Events"),
word_n_volunteers = if_else(n_volunteers == 1, "Freiwillige*r", "Freiwillige"),
word_n_pieces = if_else(n_pieces == 1, "gesammeltes Plastikstück", "gesammelte Plastikstücke"),
longlat = sf::st_centroid(geometry),
long = purrr::map_dbl(longlat, function(x) x[[1]]),
lat = purrr::map_dbl(longlat, function(x) x[[2]])
)
# Konvertierung
karten_daten <- sf::st_as_sf(karten_daten)
```
Nun **initialisieren** wir die **Karte** mit der Funktion `leaflet::leaflet()` und den angefügten, geometrischen Daten. Das **Kartenlayout** könnt Ihr unter verschiedenen Anbietern (engl. Providern) aussuchen - wir entscheiden uns hier für CartoDB mit dem Layout "Positron" und referenzieren dies in der Funktion `leaflet::addProviderTiles()` mit `providers$CartoDB.Positron`. Der Zugriff auf die Providers erfolgt wie bei den Spalten mit `$`, während `CartoDB.Positron` einfach der Name des Eintrags ist. Alle Layoutoption findet Ihr in dieser [interaktiven Übersicht](https://leaflet-extras.github.io/leaflet-providers/preview/){target="_blank"} - wie findet Ihr `CartoDB.DarkMatter`?
```{r karte, exercise = TRUE}
# Create a continuous palette function
pal <- colorQuantile(
palette = "Blues",
na.color = "#808080",
domain = karten_daten$n_volunteers,
n = 4)
### Karte mit aktiven Ländern erstellen
# Initialisierung über die geometrischen Daten
leaflet::leaflet() %>%
# Layout wählen - wir empfehlen die Layouts von CartoDB (auch verfügbar ohne Labels und in schwarz)
leaflet::addProviderTiles(providers$CartoDB.Positron) %>%
# Ausschnitt wählen
leaflet::setView(lng = 0, lat = 0, zoom = 1.2) %>%
leaflet::addPolygons(data = karten_daten$geometry,
# Beschriftung: Label (erscheint bei Hover)
label = glue::glue("{karten_daten$country}: {karten_daten$n_events} {karten_daten$word_n_events}, {karten_daten$n_volunteers} {karten_daten$word_n_volunteers}, {karten_daten$n_pieces} {karten_daten$word_n_pieces}"),
fillColor = pal(karten_daten$n_volunteers),
color = "#808080",
weight = 1, smoothFactor = 0.5, opacity = 1.0, fillOpacity = 0.5,
highlightOptions = highlightOptions(
weight = 1,
color = "#808080",
fillOpacity = 0.7,
bringToFront = TRUE),
# Beschriftung: Popup (erscheint bei Klick)
popup = glue::glue("{karten_daten$country}: {karten_daten$n_events} {karten_daten$word_n_events}, {karten_daten$n_volunteers} {karten_daten$word_n_volunteers}, {karten_daten$n_pieces} {karten_daten$word_n_pieces}"))
```
Neben `ggplot2` und `leaflet` gibt es noch ein drittes R-Package, das es euch erlaubt Visualisierungen zu erstellen: [`echarts4r`](https://rstudio.github.io/leaflet/morefeatures.html).
Ähnlich wie `leaflet` baut es auf einer JavaScript-Bibliothek auf und unterliegt in seiner Programmierlogik wie `ggplot2` und `leaflet` einer Schichtlogik und funktioniert auch über die Pipe `%>%`, die Ihr aus dem `tidyverse` und auch `leaflet` kennt. Die Visualisierungen sind hier auch interaktiv, es gibt z.B. Tooltips (zusätzliche Informationen), die angezeigt werden, wenn Betrachter:innen mit der Maus über die Visualisierung fahren.
### **Und jetzt Ihr** (diese Woche optional)
Diesmal werden wir Euch kein Rmd vorgeben - es ist Zeit zu testen, was Ihr gelernt habt! Generiert aus den **Top10-Herstellern**, die wir im letzten Kapitel aus dem Datensatz gefiltert haben, ein **Balkendiagramm**. 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?
*Tipp: Nutzt die Infrastruktur und recycelt Code aus den letzten Übungen. Innerhalb von `geom_bar()` müsst Ihr das Argument `stat = "identity" setzen.*
### **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/lernplattform/blob/main/cheatsheets/07_cheatsheet-ggplot2.pdf){target="_blank"}
- Mehr Informationen zu [`leaflet` (engl.)](https://leafletjs.com/){target="_blank"}
- [RStudios Tutorial zu leaflet (engl.)](https://rstudio.github.io/leaflet/){target="_blank"}
- Mehr Informationen zu [`echarts4r` (engl.)](https://echarts4r.john-coene.com/index.html){target="_blank"}
- [Data to Viz](https://www.data-to-viz.com/){target="_blank"}
- [R Graph Gallery ](https://www.r-graph-gallery.com/){target="_blank"}(Übersicht über verschiedene Visualisierungen)
- 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"}