R Code [zeigen / verbergen]
::p_load(tidyverse, readxl, latex2exp, see, duke,
pacman
wesanderson, ggbreak, patchwork, ggrepel, tidyplots, conflicted)
{ggplot}
CookbookLetzte Änderung am 20. May 2025 um 15:10:24
“Frei ist, wer missfallen kann.” — Annette Oschmann in Mädchen stärken
Dieses Kapitel wird in den nächsten Wochen geschrieben. Ich plane zu Beginn des WiSe 2025/26 eine arbeitsfähige Version des Kapitels erstellt zu haben. Das Kapitel wird etappenweise geschrieben, daher bleibt hier alles soweit erstmal mehr oder minder funktional.
Dieses Kapitel dient dazu Programmierung in {ggplot}
zu präsentieren. Es ist eine Sammlung von Code und Rezepten, die ich immer mal wieder nutze und immer wieder vergesse. Deshalb hat dieses Kapitel auch den Titel Cookbook. Wenn dich also Rumfummeln in {ggplot}
interessiert, dann kannst du dir hier noch was anschauen. Das Kapitel ist eigentlich nie fertig, da ich sicherlich immer mal wieder was ergänzen werde.
In diesem Kapitel geht es hauptsächlich um
Wir wollen folgende R Pakete in diesem Kapitel nutzen.
::p_load(tidyverse, readxl, latex2exp, see, duke,
pacman
wesanderson, ggbreak, patchwork, ggrepel, tidyplots, conflicted)
An der Seite des Kapitels findest du den Link Quellcode anzeigen, über den du Zugang zum gesamten R-Code dieses Kapitels erhältst.
<- read_xlsx("data/fleas_model_data.xlsx") |>
ggplot_tbl mutate(animal = as_factor(feeding),
stage = as_factor(stage))
Betrachten wir als erstes einen Auszug aus der Datentabelle.
.id | feeding | stage | weight | hatched | K | Mg | CRP | Hb | BSG | jump_length | count_leg | bonitur | infected | M |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | sugar_water | adult | 16.42 | 516.41 | 33.67 | 17.8 | 9.74 | 108.18 | 50.31 | 70.9 | 63.4 | 4 | 1 | 3971.61 |
2 | sugar_water | adult | 12.62 | 363.5 | 41.93 | 17.54 | 8.22 | 112.81 | 47.63 | 50.75 | 53.96 | 1 | 0 | 2064.13 |
3 | sugar_water | adult | 15.57 | 303.01 | 39.41 | 17.11 | 7.55 | 96.17 | 47.42 | 62.22 | 120.44 | 2 | 0 | 1763.43 |
… | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
46 | ketchup | juvenile | 7.18 | 429.18 | 32.45 | 19.53 | 15.67 | 81.7 | 15.6 | 41.08 | 423.07 | 4 | 1 | 20623.49 |
47 | ketchup | juvenile | 6.6 | 629.58 | 28.84 | 21.37 | 15.27 | 80.79 | 19.44 | 49.68 | 550.97 | 5 | 1 | 25149.36 |
48 | ketchup | juvenile | 4.19 | 192.66 | 26.61 | 20.06 | 13.95 | 80.32 | 16.07 | 43.28 | 873.28 | 5 | 0 | 21972.23 |
old stuff
<- read_excel("data/flea_dog_cat.xlsx") |>
flea_dog_cat_tbl mutate(animal = as_factor(animal))
Im Folgenden dann noch eine Sammlung an nützlichen Optionen und Möglichkeiten, die einem das Leben einfacher machen und die Abbildungen dann noch schöner. Nicht alles musst du in ggplot
machen, manchmal geht es dann in PowerPoint dann doch schneller mal eben einen Text zu ergänzen. Sehe das hier deshalb als Ergänzung und meinen privaten Raum, den ich nutze um mir den Code zu merken.
Exploratory Data Analysis Checklist
Principles of Effective Data Visualization
Principles of Effective Data Visualization (PDF-Datei)
{ggrepel}
Getting started with {ggrepel}
{ggtext
}: Improved text rendering support for ggplot2
update_geom_defaults("label",
list(family = "IBM Plex Sans Condensed"))
update_geom_defaults(ggtext::GeomRichText,
list(family = "IBM Plex Sans Condensed"))
update_geom_defaults("label_repel",
list(family = "IBM Plex Sans Condensed"))
ggplot(tibble(x = 1:3, y = 1:3), aes(x,y)) +
theme_minimal(base_family = "IBM Plex Sans Condensed") +
geom_point() +
labs(x = "Hallo", y = "Mehr zesz")
https://statisticaloddsandends.wordpress.com/2021/07/08/using-different-fonts-with-ggplot2/ https://www.r-bloggers.com/2019/03/adding-custom-fonts-to-ggplot-in-r/ https://stackoverflow.com/questions/34522732/changing-fonts-in-ggplot2 https://ggplot2.tidyverse.org/articles/ggplot2-specs.html
{gganimate}
{ggh4x}
{ggsignif}
{tidyplots}
|>
ggplot_tbl tidyplot(x = animal, y = jump_length, color = animal) |>
theme_minimal_y() |>
add_data_points() |>
add_mean_bar(alpha = 0.4) |>
add_sd_errorbar() |>
remove_legend() |>
adjust_size(height = NA, width = NA)
Engler (2025)
{ggplot}
Quick and easy ways to deal with long labels in ggplot2
Adding Custom Fonts to ggplot in R
Die Sache mit der Schriftart in {ggplot}
.
Wenn du mehr machen willst, also die Überschriften anpassen oder aber die Achsenbeschriftung ändern, dann gibt es hier global Hilfe im ggplot Manual. Die Webseite R Cookbook hat auch spezielle Hilfe für ggplot().
In Abbildung 15.3 siehst du eine Abbildung mit Titel und veränderten Beschriftungen. Die Möglichkeiten sind nahezu unbegrenzt und sprengen auch hier den Rahmen. Im Zweifel im R Tutorium vorbeischauen oder aber in der Vorlesung fragen.
ggplot(data = flea_dog_cat_tbl, aes(x = animal, y = jump_length,
fill = animal)) +
geom_boxplot() +
labs(title = "Frischgewicht in Abhängigkeit von der Behandlung",
x = "Behandlung", y = "Frischgewicht in kg/ha") +
scale_x_discrete(labels = c("Katze", "Hund")) +
scale_fill_discrete(name = "Behandlung", labels = c("Katze", "Hund")) +
theme_minimal()
Wenn du eine Abbildung abspeichern willst, dann musst du nur nach dem ggplot
-Code die Funktion ggsave()
setzen. Wie du im hier im Folgenden siehst, speichere ich die Abbildung der Boxplots der Hunde- und Katzenflöhe einmal in der Datei flea_dog_boxplot.png
ab. Dabei wähle ich eine Breite width
und eine Höhe height
von jeweils 5. Du musst dann immer etwas spielen, je größer die Zahlen, desto größer die Abbildung und die Auflösung.
ggplot(data = flea_dog_cat_tbl,
aes(x = animal, y = jump_length)) +
geom_boxplot()
## Abspeichern des obigen ggplots
ggsave("flea_dog_boxplot.png", width = 5, height = 5)
Wie immer hilft auch die Hilfeseite von ggsave()
weiter, wenn es um mehr Optionen und Qualität der Abbildungen geht.
Häufig wollen wir nicht nur einfache Achsenbeschriftungen haben, sondern auch irgendwie komplexere Einheiten wie Eisendüngergehalt im Boden in \([kg\, ha]^{-1}\) darstellen. Jetzt soll die Einheit auch in dieser Form mit in die Achsenbeschriftung. Wir können dafür zwei Wege wählen. Einmal über das R Paket {latex2exp}
und die Funktion TeX()
oder aber die Funktion expression()
, wofür wir dann kein eigenes R Paket brauchen. Beide Wege haben Vor- und Nachteile. Wir gehen aber beide mal durch. Mehr Informationen durch das Tutorium Using latex2exp oder aber eben der Klassiker mit Plot math expression.
Wir können die Funktion expression()
nutzen um uns mathematische Formeln zu bauen. Leider ist das Ganze etwas frickelig und auch ich brauche immer drei Anläufe, bis die Formel dann passt. Im Folgenden aber einmal zwei Beispiel für mathematische Formeln und Ausdrücke. Beachte, dass du jedes Leerzeichen durch eine Tilde ~
abbilden musst. Ich nutze die Funktion expression()
sehr selten und nur wenn die Formel wirklich sehr einfach ist. Da wir aber schon mit eckigen Klammern Probleme kriegen und diese so nervig mit "
einklammern müssen, nutze ich dann das Paket {latex2exp}
was ich im Folgenden vorstellen werde.
Hier aber erstmal zwei Beispiele für eine Formel mit der Funktion expression()
. Wenn du mehr über die Möglichkeiten wissen willst, dann schauen auch einmal auf die Hilfeseite von Plot math oder du googelst dir die Lösung wie ich früher zusammen.
plot(expression(Eisendüngeform~und~-höhe~"[kg ha]"^-1), cex = 1.5, main = "")
plot(expression(Fe-Gehalt~"["~mg%.%(kg~TM)^-1~"]"), cex = 1.5, main = "")
Für mich ausdrücklich einfacher geht es mit dem R Paket {latex2exp}
und der Funktion TeX()
sowie die Helferfunktion r"()"
. Ja, hier muss man dann noch eine andere Programmiersprache kennen, aber wie immer, du wirst nur schlauer. Die Informationen zur Matheumgebung in \(\LaTeX\) kommen dann nochmal extra zwischen zwei Dollarzeichen $
. Ja, das ist etwas wirr für einen Anfänger, aber wir nutzen hier auch zwei Programmiersprachen zusammen. Zum einen \(\LaTeX\) um die Mathesymbole sauber darzustellen und dann R um die Abbildungen in ggplot()
zu bauen. Mehr Informationen zu der Matheumgebung in \(\LaTeX\) findest du einmal in der LaTeX Mathehilfe I sowie der LaTeX Mathehilfe II.
Wie bauen wir uns also unseren mathematischen Ausdruck? Als erstes brauchen wir die Funktion Tex()
, die sagt einfach nur aus, dass jetzt \(\LaTeX\)-Code kommt. Dann wollen wir noch einen String brauen in dem der \(\LaTeX\)-Code für unseren mathematischen Ausdruck drin steht. Diesen String bauen wir mit r"()"
. Achtung, hier ist das Gänsefüßchen oben und unten vor und nach der runden Klammer sehr wichtig. In den Ausdruck können wir dann Text schreiben Eisengehalt
oder aber einen mathematischen Ausdruck abgrenzt von zwei Dollarzeichen $
wie $[kg\, ha]^{-1}$
. \(\LaTeX\) kann nämlich nicht nur mathematische Ausdrücke sondern ist eigentlich ein Textverarbeitungsprogramm. Deshalb musst du hier nochmal zwischen Text und mathematischen Ausdruck unterscheiden.
Hier nochmal aufgeschlüsselt wie der Code aussieht. Wir schreiben den Code nachher in einer Zeile, aber zum Verständnis ist es besser, wenn wir den Code einmal aufgeklappt sehen.
TeX(
"(
r Eisengehalt $[kg\, ha]^{-1}$
)"
)
Wir wollen uns das Ergebnis einmal in einem simplen plot()
anschauen. Wir nutzen die Funktionalität natürlich später in ggplot
, aber hier ist es so einmal einfacher zu sehen.
Auch können wir sehr viel komplexere Formeln erstellen. Beachte auch hier, dass wir zwei Matheumgebungen in \(\LaTeX\) vorliegen haben.
plot(cex = 2, main = "",
TeX(r"(
A $\LaTeX$ formula: $\frac{2hc^2}{\lambda^5}\frac{1}{e^{\frac{hc}{\lambda k_B T}} - 1}$
)")
)
In der Abbildung 15.4 dann nochmal die Anwendung in einem ggplot
in dem wir die Achsen entsprechend beschriften und dann auch noch eine ausgedachte Regressionsgeleichung zu der Abbildung ergänzen.
ggplot(data = flea_dog_cat_tbl, aes(x = flea_count, y = jump_length)) +
geom_point() +
stat_smooth(method = "lm", se = FALSE) +
theme_minimal() +
labs(x = TeX(r"(Eisengehalt und -höhe $[kg\, ha]^{-1}$)"),
y = TeX(r"(Fe-Gehalt $[mg \cdot (kg TM)^{-1}]$)")) +
annotate("text", x = 10, y = 10,
label = TeX(r"($y = \beta_0 + \beta_1 \cdot x;\; R^2 = 0.24$)"))
Wenn du dann mal die Funktion Tex()
in geom_text()
verwenden willst, dann musst du einmal etwas anpassen. Dann klappt es aber auch hier. Das hat mich mal echt Nerven und Zeit gekostet, deshalb lagere ich die Information mal hier für mich.
ggplot() +
theme_void() +
geom_text(aes(0, 0,
label = TeX(r'($\alpha x^\alpha$, where $\alpha \in 1\ldots 5$)',
output = "character")), parse = TRUE)
Neben den klassischen Farben im R Paket {ggplot2}
gibt es noch weit, weit mehr Farbpaletten. Wir nutzen in der Folge immer wieder die Okabe-Ito Farbpalette aus dem R Paket {see}
. Die Okabe-Ito Farbpalette ist speziell so gebaut, dass die Farben sich gut für farbenblinde Personen unterscheiden. Mehr zum R Paket {see}
auf der Hilfeseite des Paketes. Der Kontrast zwischen den Farben ist sehr gut. Wenn du eine andere Farbpalette nutzen willst, findest du hier noch andere Color Scales.
ggplot(data = flea_dog_cat_tbl,
aes(x = animal, y = jump_length,
fill = animal)) +
geom_boxplot() +
scale_fill_okabeito() +
theme_minimal()
ggplot(data = flea_dog_cat_tbl,
aes(x = animal, y = jump_length,
color = animal)) +
geom_point() +
scale_color_okabeito() +
theme_minimal()
Das Ganze geht dann auch händisch mit dem folgenden Code für die jeweiligen Farben. Anbei einmal die Farbpalette dargestellt.
Die Farben sind dann in der Reihenfolge wie folgt kodiert.
<- c("#E69F00", "#56B4E9", "#009E73",
cbbPalette "#F0E442", "#0072B2", "#D55E00",
"#CC79A7", "#999999", "#000000")
Wenn wir Boxplots einfärben wollen dann nehmen wir den folgenden Code.
scale_fill_manual(values = cbPalette)
Und das hier ist die Ergänzung für Punkte und Linien.
scale_colour_manual(values = cbPalette)
Neben der Okabe-Ito Farbpalette liefert das R Paket {duke}
noch eine andere Möglichkeit eine Farbpalette für Farbblinde zu generieren.
Die Farben sind dann in der Reihenfolge wie folgt kodiert.
<- c("#012169", "#C84E00", "#00539B", "#339898",
dukePalette "#A1B70D", "#E89923", "#FFD960", "#262626")
Die Funktionen hier sind scale_duke_color_discrete()
sowie scale_duke_continuous()
und scale_duke_fill_discrete()
.
Manchmal benötigen wir auch Farbverläufe. In R heißen diese Farbverläufe dann Farbpaletten. Eine Einführung liefert das Tutorium Using RColorBrewer palettes. Ich selber nutze gerne das R Paket {wesanderson}
welches sehr schöne Farbverläufe hat. Mehr kannst du auf der GitHub Seite Wes Anderson Palettes erfahren. Wir können die Paletten ganz einfach mit der Funktion wes_palette()
laden.
Das schöne ist hier, dass wir einfach wie folgt Farbverläufe erstellen können. Wir wollen hier 21 Farbwerte haben und das Ganze dann als kontinuierlichen Verlauf.
Das R Paket {patchwork}
erlaubt es mehrere ggplot
Abbildungen nebeneinander oder in einem beliebigen Layout miteinander zu verbinden. Das tolle ist, dass die Idee sehr intuitiv ist. Wir nutzen wieder das +
um verschiedene Plots miteinander zu verbinden. Im Folgenden erschaffen wir uns zwei ggplots
und speichern die Plots in den Objekten p1
und p2
. Das ist wie wir es bisher kennen, nur das jetzt keine Abbildung erscheint sondern beide Plots in zwei Objekten gespeichert sind.
<- ggplot(data = flea_dog_cat_tbl,
p1 aes(x = flea_count, y = jump_length,
color = animal)) +
geom_point() +
scale_color_okabeito() +
theme_minimal()
<- ggplot(data = flea_dog_cat_tbl,
p2 aes(x = animal, y = jump_length,
color = animal)) +
geom_point() +
scale_color_okabeito() +
theme_minimal()
Wie können wir nun die beiden Abbildungen nebeneinander zeichnen? Wir nutzen einfach das +
Symbol.
+ p2 p1
Auf der Seite des R Paket {patchwork}
findest du viel mehr Möglichkeiten das Layout anzupassen und auch die einzelnen Subplots zu beschriften.
Das R Paket {ggbreak}
erlaubt es dir in die \(x\)-Achse oder aber \(y\)-Achse Lücken einzusetzen oder aber die Achsen eben gebrochen darzustellen. Zur Demonstration bauen wir uns nochmal den stat_tbl
für die Hunde- und Katzenflöhe. Wir berechnen hier dann die Mittelwerte und nicht mehr die Standardabweichung, da es sonst nicht so gut mit der Darstellung mit der gebrochenen \(y\)-Achse für dieses Beispiel klappt.
<- flea_dog_cat_tbl |>
stat_tbl group_by(animal) |>
summarise(mean = mean(jump_length))
In der Abbildung 15.10 siehst du einmal die Abbildung der Mittelwerte der Sprungweiten der Hunde- und Katzenflöhe als Barplots dargestellt. Ich habe hier einen Bruch auf der \(y\)-Achse mit der Funktion scale_y_break()
bei 1 bis 4 eingefügt und den Abstand über die Option space
etwas visuell vergrößert. Mit der Option scales
könntest du dann noch die Skalierung der gebrochenen \(y\)-Achse anpassen.
ggplot(stat_tbl, aes(x = animal, y = mean, fill = animal)) +
theme_minimal() +
geom_bar(stat = "identity") +
scale_y_break(c(1, 4), space = 0.5)