-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy path09-Visualisierung.Rmd
494 lines (366 loc) · 21.5 KB
/
09-Visualisierung.Rmd
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
---
output: html_document
editor_options:
chunk_output_type: console
---
# (PART) Der Spaßige Teil {-}
```{r load_fonts, include=FALSE}
# Fancy font stuff required for hrbrthemes
hrbrthemes::import_roboto_condensed()
extrafont::loadfonts()
library(ggplot2)
library(dplyr)
library(tadaatoolbox)
```
# Visualisierung
Es hat ein bisschen gedauert, aber wir mussten uns zuerst erarbeiten, wie wir eigentlich in R mit Daten umgehen können und grob verstehen wie sich R überhaupt verhält, bis wir endlich was spaßiges machen können.
Und Datenvisualisierung ist vermutlich so ziemlich das spaßigste, was wir in R anstellen können. Eine gute Visualisierung (*Plot*) ist aussagekräftigter als jede schnöde Tabelle, kann unintuitive Zusammenhänge aufdecken und die Interpretation eurer Daten deutlich vereinfachen.
Deswegen ist der erste Schritt jeder Datenanalyse ein Plot der Daten in verschiedenen Formen um ein Gefühl für die Struktur und die Zusammenhänge dieser Daten zu bekommen.
## ggplot2
[ggplot2](http://ggplot2.tidyverse.org/) ist nicht nur ein R-Packages, es ist auch gleichzeitig eine Implementation des *Grammar of Graphics*. Das klingt fancy (ist es auch), heißt für uns aber in erster Linie nur, dass es gut durchdachter Kram ist.
```{r}
library(ggplot2)
```
*ggplot2* baut euch einen Plot aus verschiedenen Elementen zusammen, und es hilft durchaus ein grobes Gefühl dafür zu haben, wie das unter der Haube aussieht.
- *geom*: Jedes *geom* ist eine *Lage* des Plots, der Grundlayer ist einfach leer. Jeder weitere Layer enthält `geom`-Elemente, wie Balken, Histogramme, Punkte etc. Ein `geom` ist eine geometrische Darstellungsform, und wenn ihr mehrere Darstellungsformen übereinanderlegen wollt, erstellt ihr damit mehrere *Layer*.
- `aes`: *Aesthetics*, die Zuordnungen einer Variable mit konkreten Werten zu einem Aspekt des Plots, wie zum Beispiel "Alter auf die x-Achse, Körpergröße auf die y-Achse".
- *scales*: Mit *scales* können wir die einzelnen *aesthetics* bearbeiten, so können wir zum Beispiel die Abstände auf der x-Achse anpassen oder die Beschriftung auf der y-Achse.
- *theme*: Optional können wir jedes optische Element des Plots manuell anpassen, sei es die Schriftart im Titel oder die Farbe des Hintergrunds, die Position der Legende.
Ein Beispiel:
```{r ggplot_firstlook}
ggplot(data = qmsurvey, aes(x = alter, y = feiern)) +
geom_col() +
scale_y_continuous(breaks = seq(0, 100, 15), minor_breaks = seq(0, 100, 5)) +
labs(title = "Alter und Feiern",
subtitle = "Wie oft gehst du im Monat feiern",
x = "Alter (Jahre)", y = "Tage pro Monat")
```
Okay, was haben wir da gemacht?
`ggplot()` macht erstmal einen neuen Plot auf. Mit `data = qmsurvey` sagen wir, mit welchem Datensatz wir arbeiten, und wo ggplot die Namen der Variablen suchen soll, die wir benutzen. `aes()` macht die Verknüpfung von Skalen (`x`, `y`) zu Variablen, soweit alles erwartungsgemäß, kein fancy Voodoo, nur gewöhnungsbedürftiger Syntax.
`geom_col` macht ein Balkendiagramm auf, und wir haben ja bereits definiert welche Variable wo hin soll.
In `scale_y_continuous` sagen wir jetzt noch, dass die Achsenabstände in 15er-Schritten liegen sollen, und wir kleinere Abstände (die dünneren weißen Linien) in 5er-Abständen liegen sollen.
Als letztes kümmern wir uns ein bisschen um die Kosmetik: Wir beschriften unsere Elemente mit `labs()`, wobei wir Title, Untertitel und Achsen beschreiben.
Im Folgenden kommen einige Beispiele, aber grundsätzlich könnt ihr euch alles auch auf der offiziellen Seite unter <http://ggplot2.tidyverse.org> anschauen, wo es auch eine [Referenz aller Funktionen mit Anwendungsbeispielen gibt](http://ggplot2.tidyverse.org/reference/index.html). Ich für meinen Teil habe am Anfang (und auch immer noch) viel Zeit damit verbracht, die Referenz nach etwas zu durchsuchen, dass so grob nach dem aussieht, was ich gerne hätte -- und das dann so lange zu tweaken bis es funktioniert.
Das Erfolgserlebnis nach ewigem Rungefummel ist nicht zu unterschätzen, aber natürlich ist es hilfreich, wenn man erstmal die Grundlagen erklärt bekommt.
## Layer: `geom_wtf`
Der visuelle Kern eines Plots ist die geometrische Verknüpfung eurer Daten auf einen *Layer*, sowas wie Punkte, Linien, Balken, ihr wisst schon. Ein Plot braucht mindestens einen *Layer* (ein *geom*) um überhaupt irgendwas anzuzeigen, und die entsprechenden Funktionen sind dankbar einfach benannt:
- `geom_point`: Macht Punkte (*Scatterplot*)
- `geom_line`: Macht Linien
- `geom_boxplot`: Boxplots
- `geom_histogram`: Histogramm (Häufigkeitsverteilung)
- `geom_bar`: Balkendiagramm mit Häufigkeiten auf der y-Achse
- `geom_col`: Balkendiagramm mit frei wählbarer y-Achse
### Barcharts & Histogramme
Eine der einfachsten Anwendungsfälle für Visualisierungen sind Balken- und Histogramme. Der Unterschied zwischen den beiden ist eher subtil: Histogramme haben eine numerische/kontinuierliche Variable auf der x-Achse, und Barcharts haben diskrete Variablen auf der x-Achse. Daraus ergibt sich auch, dass Barcharts immer einen Balken pro Merkmalsausprägung haben.
Die y-Achse ist jeweils die Häufigkeit, mit der die jeweilige Variable auftritt. Diese wird in der Regel als absolute Häufigkeit in ggplot2 angezeigt, aber wir können auch relative Häufigkeiten oder *densities* verwenden.
```{r barchart}
# Balkendiagramm
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar()
# Balken mit relativen Häufigkeiten
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar(aes(y = ..prop..))
```
Das ist zwar schön und gut, aber es sieht noch nicht so wirklich brauchbar aus, und es fehlen vor allem aussagekräftige Beschriftungen. Letztere sind via `labs()` sehr einfach:
```{r barchart_labs}
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar() +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
#### `geom_bar` vs. `geom_col` vs `geom_histogram`
Diese drei `geom`s machen *ähnliche* Dinge, nämlich *irgendwas mit Balken(ish)*, aber sie sind nicht beliebig austauschbar.
In Kürze:
- `geom_histogram`: Histogramm für **numerische, stetige** Variablen
- `geom_bar`: Häufigkeitsverteilung in Balkenform für **diskrete** Variablen (numerisch oder kategorial)
- `geom_col`: Für bivariate Plots mit einem **diskreten** Merkmal auf der *x-Achse* und einer **numerischen** Variable auf der **y-Achse**
Ein gängiger Anwendungsfall für `geom_col` wäre es, Häufigkeiten zu plotten, die wir vorher manuell berechnet haben. Ein Beispiel:
```{r geom_col_1}
qmsurvey %>%
count(gender, rauchen) %>%
group_by(gender) %>%
mutate(prop = round(n/sum(n), 4))
```
Hier haben wir die relativen Häufigkeiten für die Merkmalsausprägungen in `rauchen` berechnet, relativ zu jeder Gruppe in `gender`.
Damit können wir sowas machen:
```{r geom_col_1_plot}
qmsurvey %>%
count(gender, rauchen) %>%
group_by(gender) %>%
mutate(prop = round(n/sum(n), 4)) %>%
ggplot(aes(x = rauchen, y = prop, fill = gender)) +
geom_col(position = "dodge", color = "black") +
scale_y_continuous(labels = scales::percent) +
labs(title = "Raucherstatus nach Gender",
subtitle = "Relative Häufigkeiten in >Gender<")
```
Ein klassisches Beispiel für "Daten erst präparieren, dann plotten". Es ist viel einfacher schnell die gruppierten Prozente zu berechnen, als *ggplot2* dazu zwingen zu wollen, die entsprechende Gruppierung und Berechnung zu übernehmen.
### Boxplots und Errorbars
```{r boxplot_basic}
ggplot(data = qmsurvey, aes(x = rauchen, y = lernen)) +
geom_boxplot()
```
Wenn ihr woanders die *base* Funktion `boxplot` <small>(ugh)</small> gesehen habt, dann habt ihr vermutlich auch univariate Boxplots gesehen, sprich keine Gruppierung. Das... kann man machen, ist aber irgendwie witzlos. Wenn ihr das _unbedingt_ mit *ggplot2* machen wollt, dann müsst ihr die x-Achse austricksen und sie auf eine Konstante setzen, wie `NA`:
```{r boxplot_single}
ggplot(data = qmsurvey, aes(x = NA, y = lernen)) +
geom_boxplot()
```
Wenn wir das dann noch in etwas schöner machen wollen, und zum Beispiel 90° rotiert:
```{r boxplot_single_prettier}
ggplot(data = qmsurvey, aes(x = NA, y = lernen)) +
geom_boxplot(alpha = .5, width = .5) +
coord_flip() +
labs(title = "Lernen") +
theme(axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank())
```
Der Teil im `theme` ist dazu da, die Labels auf der y-Achse zu verstecken, damit wir das `NA` aus unserem kleinen Trick da rauskriegen.
Ansonsten ist das Ding immer noch ziemlich langweilig, aber naja.
Meine derzeit präferierte Art Boxplots zu bauen ist ein Boxplot mit Punkten im Hintergrund, um die Menge und grobe Verteilung der Werte besser zu veranschaulichen:
```{r boxplot_pints}
ggplot(data = qmsurvey, aes(x = rauchen, y = lernen, color = rauchen)) +
geom_point(position = "jitter") +
geom_boxplot(alpha = .25, outlier.alpha = 0) +
scale_color_brewer(palette = "Dark2", guide = FALSE)
```
Hier setzen wir noch das `alpha` für die Ausreißer im Boxplot auf `0`, weil wir ja durch das `geom_point` sowieso alle Punkte geplottet haben.
*"Und was ist mit den **Whiskern**?"* höre ich spitzfindige Lesende im Kanon kreischen.
Öhm, naja, Whisker können wir über *Error Bars* simulieren, in etwa so:
```{r boxplot_whisker}
ggplot(data = qmsurvey, aes(x = rauchen, y = lernen, color = rauchen)) +
stat_boxplot(geom = "errorbar", width = .5) +
geom_boxplot() +
scale_color_brewer(palette = "Dark2", guide = FALSE)
```
**Error Bars** sind auch so ganz nützlich, zum Beispiel für Konfidenzintervalle. Wir müssen die KIs nichtmal selber berechnen, genauso wie wir für Boxplots keine Quartile berechnen müssen.
```{r errorbars}
ggplot(data = qmsurvey, aes(x = rauchen, y = lernen, color = rauchen)) +
stat_summary(fun.data = mean_cl_normal, geom = "errorbar") +
scale_color_brewer(palette = "Dark2", guide = FALSE)
```
Hier haben wir 95% Konfidenzintervalle um den Mittelwert. Wir ihr seht, reicht nicht einfach ein `geom_errorbar`, weil Error Bars zu allgemein sind und nicht immer automatisch mit den selben Werten angewendet werden, wie wir es bei Boxplots gewohnt sind.
Wir können hier auch zusätzlich noch die Mittelwerte einzeichnen:
```{r errorbars_2}
ggplot(data = qmsurvey, aes(x = rauchen, y = lernen, color = rauchen)) +
stat_summary(fun.data = mean_cl_normal, geom = "errorbar", position = "dodge") +
stat_summary(fun.y = mean, geom = "point", size = 3) +
scale_color_brewer(palette = "Dark2", guide = FALSE)
```
### Scatterplots und Regressionsgerade
Scatterplots sind, grob gesagt, *das mit den Punkten*.
Am besten geeignet sind sie für bivariate Visualisierung zweier numerischer Variablen,
wie etwa die Zufriedenheit im Studium abhängig vom Alter:
```{r scatter_1}
ggplot(data = qmsurvey, aes(x = alter, y = zufrieden)) +
geom_point()
```
Das Problem an dieser Stelle ist, dass wir sehr viele Punkte haben, die sich überlagern, und wir daher nicht einschätzen können, wie die verteilung tatsächlich aussieht. Eine einfache Möglichkeit ist hier *jittering*, wir lassen also alle Punkte ein bisschen *"jittern"*:
```{r jitter_1}
ggplot(data = qmsurvey, aes(x = alter, y = zufrieden)) +
geom_point(position = "jitter")
```
Das Problem hierbei ist, dass wir die Punkte ja minimal verfälschen. Für etwas mehr Kontrolle können wir auch direkt `geom_jitter` benutzen, das uns etwas mehr Kontrolle gibt:
```{r jitter_2}
ggplot(data = qmsurvey, aes(x = alter, y = zufrieden)) +
geom_jitter(width = .1, height = .1)
```
Hier sagen wir den Punkten, dass sie maximal 10% horizontal oder vertikal *jittern* sollen, was unsere Daten weniger verzerrt, aber uns immernoch einen etwas besseren Einblick erlaubt.
Wir können auch die Punktgröße abhängig von der Anzahl der Datenpunkte an jeder Stelle machen, dafür brauchen wir allerdings etwas *data munging* im Vorfeld.
```{r point_sizes}
qmsurvey %>%
count(alter, zufrieden) %>%
ggplot(aes(x = alter, y = zufrieden, size = n)) +
geom_point()
```
Mit `count` haben wir hier jede Kombination aus `alter` und `zufrieden` durchgezählt und eine Variable `n` erhalten, und von dieser machen wir so die Punktgröße abhängig. Größerer Punkt, mehr Datenpunkte an dieser Stelle. Einfach. Gut sichtbar.
Als nächstes können wir lineare Zusammenhänge veranschaunlichen, indem wir **Regressionsgeraden** durch unsere Punkte ziehen. Als Beispiel anhand der Variablen `arbeit` und `lernen`:
```{r smooth_lm}
ggplot(data = qmsurvey, aes(x = lernen, y = arbeit)) +
geom_point() +
geom_smooth(method = lm, se = FALSE)
```
Sieh an, wer mehr lernt, hat weniger Zeit zum arbeiten. So grob.
`geom_smooth` kann beliebige Arten von Schätzlinien durch eure Daten ziehen, in diesem Fall sagen wir mit `method = lm`, dass es eine Regressionsgerade aus einem **Linearen Modell** werden soll, mittels der gleichnamigen Funktion `lm`. Zusätzlich sagen wir mit `se = FALSE`, dass wir kein Konfidenzband wollen.
Wenn ihr `geom_smooth` ohne Zusatzargumente benutzt, bekommen ihr ein `loess`-Smoothing mit Konfidenzband. Loess ist ziemlich schnieke von dem was es tut, aber in der Regel nicht inhaltlich relevant für unsere relativ simplen Anwendungsfälle:
```{r smooth_loess}
ggplot(data = qmsurvey, aes(x = lernen, y = arbeit)) +
geom_point() +
geom_smooth()
```
Spooky. Lokale polynomiale Regression und so. Wenn euch langweilig ist, lest die Hilfe in `?loess`, ansonsten sei nur gesagt, dass wir das im Kontext linearer Regression nicht benutzen.
Achja, wir können natürlich auch unsere Punkte beliebig einfärben, zum Beispiel nach einer Drittvariable:
```{r point_col}
ggplot(data = qmsurvey, aes(x = lernen, y = arbeit, color = gender)) +
geom_point() +
scale_color_brewer(palette = "Set1")
ggplot(data = qmsurvey, aes(x = lernen, y = arbeit, color = gender)) +
geom_point() +
geom_smooth(method = lm, se = FALSE) +
scale_color_brewer(palette = "Set1")
```
Zu Farbpaletten kommen wir weiter unten nochmal, aber hier sehen wir schonmal ein einfaches Beispiel für einen Scatterplot zweier Variablen mit Farbkodierung nach einer Drittvariable.
Mehr als 3 Variablen auf einem Scatterplot zu verbauen würde ich auch nicht empfehlen, auch wenn es theoretisch möglich wäre.
Ein Maximalbeispiel sensorischer Überforderung:
```{r dont_do_this}
ggplot(data = qmsurvey, aes(x = lernen, y = arbeit,
color = gender, fill = rauchen,
alpha = zufrieden, size = alter)) +
geom_point(shape = 21, stroke = 2) +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Dark2") +
theme(legend.position = "bottom",
legend.box = "vertical")
```
Das ist albern. Was wir hier haben:
- `color`: Umrandungsfarbe abhängig von `gender`
- `fill`: Füllfarbe abhängig von `rauchen`
- `alpha`: Transparenz abhängig von `zufrieden`
- `size`: Größe abhängig von `alter`
Sowas einfach nicht machen.
### Facetting
### Spaßiger Kram
Via <https://fronkonstin.com/>:
```{r generativeart}
library(dplyr)
library(ggplot2)
seq(from = -10, to = 10, by = 0.05) %>%
expand.grid(x = ., y = .) %>%
ggplot(aes(x = (x + pi * sin(y)), y = (y + pi * sin(x)))) +
geom_point(alpha = .1, shape = 20, size = 1, color = "black") +
coord_equal() +
theme_void()
```
Das fällt unter den Punkt "generative art", und ist durchaus schön, aber geht auch ein bisschen auf die CPU.
## Mach mal bunt!
Okay, wir wollen also die Balken bunt machen. Es gibt zwei Möglichkeiten: Die `color` und `fill`. Ersteres ist die Farbe (duh), zweiteres die Füllfarbe (duhuh), und unterschiedliche `geoms` haben da entsprechende Unterschiede.
```{r colorfill_1}
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar(color = "red") +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
Jetzt haben wir rote Umrandungen. Nicht sehr beeindruckend.
```{r colorfill_2}
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar(fill = "red") +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
Ein bisschen grell, aber immerhin rot.
```{r colorfill_3}
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar(fill = "darkred", color = "black") +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
Okay, vielleicht ein bisschen Transparenz noch?
```{r colorfill_4}
ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar(fill = "darkred", color = "black", alpha = 0.75) +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
`alpha` gibt die Durchsichtigkeit des Elements an, von `0` (unsichtbar) bis `1` (keine Transparenz).
Was die Farben angeht: R kennt `red` und `darkred` neben etlichen anderen Farben. Diese Farben könnt ihr euch via `colors()` ausgeben lassen — also zumindest die Namen der Farben.
Alternativ könnt ihr Farben auch als Hex-String angeben, rot wäre dann zum Beispiel `#FF0000`. Wenn ihr mal "rgb color picker" googlet, findet ihr auch entsprechende tools, oder ihr installiert das `colourpicker` package und habt dann sowas direkt in RStudio unter "Addins":
```{r, echo=FALSE, out.width="75%", fig.cap="Colourpicker RStudio Addin"}
knitr::include_graphics("images/colorpicker.png")
```
### `scale_color_*` und `scale_fill_*`
Wenn wir global die Farbe der Balken ändern wollen, können wir das direkt simpel im `geom_bar()`-Element machen, aber manchmal wollen wir ja auch die Farbe abhängig von einer anderen Variable machen.
Wenn wir einer *aesthetic* wie `fill` oder `color` eine Variable zuordnen wollen, müssen wir das in `aes()` tun, wo wir auch `x` und `y` definieren.
```{r scales_1}
ggplot(data = qmsurvey, aes(x = rauchen)) +
geom_bar()
```
```{r scales_2}
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar()
```
```{r scales_3}
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar(position = "dodge", color = "black", alpha = .75)
```
Jetzt haben wir Balken, gefärbt in Abhängigkeit von der Variable `gender`, in den ggplot2-Standardfarben.
Wenn wir bestimmte Farben für die Zuordnung benutzen wollen, müssen wir die entsprechende `scale` manuell bearbeiten.
Unter `scale` fällt in ggplot2 jedes Element eines Plots, das sich einer Variable zuordnen lässt, dazu gehören `x` und `y`-Variablen, aber auch die Farbe `color` und Füllfarbe `fill`.
Also, ein paar Beispiele:
```{r scales_4}
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar() +
scale_fill_manual(values = c("red", "blue", "green"))
```
Oh glob, viel zu grell!
```{r scales_5}
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar() +
scale_fill_manual(values = c("darkred", "lightblue", "darkgreen"))
```
Besser, aber auch hässlich, nur anders.
Es stellt sich heraus, dass Farben kompliziert sind. Zumindest, wenn man Ansätze von ästhetischem Anspruch hat.
Zum Glück sind wir aber nicht auf manuelle Farbauswahl angewiesen, wir können fertige Farbpaletten benutzen, bei denen sich schonmal jemand Gedanken darüber gemacht hat, ob das okay aussieht oder nicht.
### Zusätzliche Farbpaletten
#### RColorBrewer
```{r colorbrewer}
# install.packages(RColorBrewer)
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar(position = "dodge", color = "black", alpha = .75) +
scale_fill_brewer(palette = "Set1")
```
Übersicht über die Farbpaletten:
```r
library(RColorBrewer)
display.brewer.all()
```
```{r, echo=FALSE, out.width="75%", fig.cap="RColorBrewer Paletten"}
knitr::include_graphics("images/brewer_palettes.png")
```
#### Viridis
Besondere Stärke: Gleicher wahrgenommener Abstand der Farben, demnach besonders gut geeignet für kontinuierliche Fabrskalen. Bonus: Auch noch gut distinguierbar, wenn in schwarzweiß konvertiert.
```{r viridis}
library(viridis)
ggplot(data = qmsurvey, aes(x = rauchen, fill = gender)) +
geom_bar(position = "dodge", color = "black", alpha = .75) +
scale_fill_viridis(discrete = TRUE, option = "plasma")
```
## Themes
Themes verändern nicht die Farbe eurer Punkte/Linien/Balken, aber sie verändern alles andere an eurem Plot, von der Hintergrundfarbe bis zur Schriftart in den Labels.
Es gibt viele schöne themes, aber der allgemeine Ratschlag bleibt: Simpel ist besser.
```{r themes_1}
plot <- ggplot(data = gotdeaths, aes(x = death_season)) +
geom_bar() +
labs(title = "Game of Thrones: Deaths",
subtitle = "Deaths per Season",
x = "Season", y = "# of Deaths")
```
```{r themes_2}
library(tadaatoolbox)
plot + theme_tadaa()
```
Oder auch:
```{r themes_3}
library(hrbrthemes)
plot + theme_ipsum_rc()
```
Siehe auch: `ggthemes`
```{r themes_4}
library(ggthemes)
plot + theme_gdocs()
plot + theme_pander()
plot + theme_fivethirtyeight()
plot + theme_excel() # Nein.
plot + theme_economist()
```
## Learning by Fiddleing
*ggplot2* zu lernen lohnt sich sehr, weil ihr nach einer Weile einfach ein intuitives Gefühl dafür bekommt, wie ihr Daten eim schnellsten und einfachsten schön präsentieren könnt.
Der Weg dahin ist voller Googlereien und ihr werde viel Zeit damit verbringen Code von anderen zu copypasten und solange daran herumzuspielen bis es so grob das macht, was ihr wollt.
Also: Googlet was ihr machen wollt, und bookmarkt [ggplot2.tidyverse.org](http://ggplot2.tidyverse.org/).
Zusätzlich gibt es da noch diese unheimlich praktische Liste gängiger Anwendungsfälle:
<http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html>.
Sucht euch den Code raus, der so grob macht was ihr wollt, und dann... happy tweaking.