Datenvisualisierung mit base R und ggplot2

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2023/2024

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • einfache Diagramme zur Datenexploration mithilfe der R Basisfunktionen erstellen können.
  • wissen, wie Grafiken als PDF, JPEG oder PNG Dateien gespeichert werden können.
  • das Prinzip der geschichten Diagrammerstellung in ggplot2 verstanden haben.
  • einen Überblick über die verschiedenen geom_XXX() Funktionen haben.
  • die wichtigsten Diagrammtypen in den entsprechenden Kategorien mit ggplot2 erstellen können.

2 verbreitete Typen

Grafiken mit base R

  • Funktionen sind bereits Bestandteil der Basisversion.
  • Gut geeignet für eine einfache und schnelle Datenexploration.
  • Nicht sehr intuitiv und weniger geeignet für komplexe Grafiken.
  • Keine gute Hilfe bzw. Dokumentation.

Grafiken mit ggplot2 Paket

  • Besser geeignet bei komplexeren Grafiken.
  • Klarere Syntax.
  • Besser dokumentiert.
  • Viele Beispiele im Internet.

Grafiken mit base R

2 Funktionstypen

High-level Funktionen

Erstellen vollständige Diagramme.

plot(x = iris$Sepal.Length, 
  y = iris$Sepal.Width)

Low-level Funktionen

Fügen weitere Elemente in den aktuellen Plot.

plot(x = iris$Sepal.Length, 
  y = iris$Sepal.Width)
abline(h = 3, lwd = 5, col = "blue") 

High-level Funktionen | Überblick

Funktion Beschreibung
plot() Generische Funktion mit vielen Methoden (kontextabhängig)
barplot() Säulen- bzw. Balkendiagram
boxplot() Boxplot
contour() Plot mit Höhenlinien
coplot() sog. ‘conditional plot’
curve() Kurven über einem Intervall für eine Funktion
hist() Histogramm
image() Erstellt kontextabhängige ‘Bildraster’ (auch in 3D)
mosaicplot() Mosaikplot für kategorielle Daten
pairs() Streudiagramm-Matrix für paarweise Gegenüberstellungen
pie() Tortendiagramm
qqplot() QQ-Plot

High-level Funktionen | Beispiele

High-level Funktionen | Dokumentation

  • Können über ihre Argumente modiziert und angepasst werden.
  • In den Hilfen von ?plot und ?plot.default werden viele Argumente von Grafikfunktionen genannt und erklärt.
  • Es gibt jedoch auch globale Einstellungen für Grafiken, die alle nachfolgenden Grafiken verändern können: par().
  • Die Hilfe von ?par listet wesentlich mehr Argumente, die auch in den high-level Funktionen genutzt werden können.

High-level Funktionen | Argumente

Argument Beschreibung
adj Ausrichtung von Text (zentriert,…)
axes Achsen sollen (nicht) eingezeichnet werden
bg Hintergrundfarbe der Grafik
bty Art der Box um die gezeichnete Grafik
cex Größe der Schriftzeichen in der Grafik
col Farben (der Linien, der Punkte, etc.)
las Ausrichtung der Achsenbeschriftung
lty,lwd Linientyp (gestrichelt,…) und Linienbreite
main,sub Überschrift und Unterschrift
mfrow mehrere Grafiken in einem Bild
pch Darstellung eines Punktes
type Typ der Darstellung (Linien, Punkte, Nichts)
xlab,ylab x-/y-Achsenbeschriftung
xlim,ylim Größe der Grafik in x-/y-Richtung

High-level Argumente | Demonstration 1

plot(
  x = 1:10,
  y = c(5,9,3,1,14,2,3,6,13,10)
)

High-level Argumente | Demonstration 2

plot(
  x = 1:10,
  y = c(5,9,3,1,14,2,3,6,13,10),
  type = "b" # =both (line + point)
)

High-level Argumente | Demonstration 3

plot(
  x = 1:10,
  y = c(5,9,3,1,14,2,3,6,13,10),
  type = "b", # =both (line + point)
  pch = 20,
  cex = 6,
  col = "red"
)

High-level Argumente | Demonstration 4

plot(
  x = 1:10,
  y = c(5,9,3,1,14,2,3,6,13,10),
  type = "b", # =both (line + point)
  pch = 20,
  cex = 6,
  col = "red",
  xlab = "X", ylab = "Y",
  main = "Grafiküberschrift"
)

Wichtige low-level Grafikfunktionen

Funktion Beschreibung
abline() Zeichnet eine kontextabhängige Linie
arrows() Zeichnet Pfeile
axis() Zeichnet Achsen (jede Achse einzeln!)
grid() Zeichnet ein Gitternetz
legend() Erstellt eine Legende im Plot
lines() Zeichnet schrittweise Linien
mtext() Schreibt Text in den Rand (s.unten)
points() Zeichnet Punkte
polygon() Zeichnet ausgefüllte Polygone
rect() Zeichnet (vektorwertig) ein Rechteck
segments() Zeichnet (vektorwertig) Linien
text() Schreibt Text in den Plot
title() Beschriftet den Plot

Wo soll die Grafik erscheinen?

Die sog. ‘graphics devices’


Screen device (default) - Fenster im Programm

File device - Ausgabeformat als Rasterdatei (JPEG, PNG, TIFF,..) oder Vektordatei (PDF, EPS)

Ausgabeformate und ihre Funktionen

Ausgabeformate | Demonstration

Screen device
plot(1:10)

→ Die Ausgabe erscheint standardmäßig auf dem Bildschirm

Ausgabe als PDF-Datei
pdf('Grafik1.pdf') # Device wird gestartet
plot(1:10) # Grafik wird erstellt
points(0.5:9.5, col=1:10, pch=1:10) # Erweiterungen
#... weitere Erweiterungen an der Grafik
dev.off() # Device muss geschlossen werden

Important

Das Schließen mit dev.off() ist besonders wichtig, sonst werden alle folgenden Grafiken mit in dem PDF gespeichert und nicht in der Konsole angezeigt!

Visualisierung mit ‘ggplot2’

Ein System für kreative Grafiken

Gallerie der ggplot2 Erweiterungen

Umsetzung des visual encoding in ggplot2

Die 8 Ebenen in ggplot2

Eine Demonstration mit dem internen Datensatz ‘iris’

Iris setosa Iris versicolor Iris virginica

Fotos von Radomil Binek, Danielle Langlois, und Frank Mayfield (von links nach rechts); Zugriff über Wikipedia(unter CC-BY-SA 3.0 Lizenz).

Ebene 1 - Data

Grafik starten mit ggplot()

ggplot(data = iris)

Ebene 2 - Aesthetic mapping | 1

Globale Variablenzuordnung von x und y

ggplot(data = iris) +
  aes(
    x = Sepal.Length, 
    y = Petal.Length)

Noch besser innerhalb der ggplot Funktion:

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  )

Ebene 3 - Geometries | 1

Punkte-Geometrie hinzufügen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point()

Ebene 3 - Geometries | 2

Die Punktfarbe einheitlich anpassen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(colour = "green")

Ebene 2 - Aesthetic mapping | 2

Variablen-spezifische Farbwahl (lokal)

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(aes(colour = Species))

Ebene 2 - Aesthetic mapping | 3

Falsch: Einheitliche Farbwahl ‘mappen’

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(aes(colour = "green"))

Ebene 3 - Geometries | 3

Weitere Geometrie hinzufügen: geglättete Kurve

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(aes(colour = Species)) +
  geom_smooth()

Ebene 3 - Geometries | 4

Weitere Geometrie hinzufügen: Trendlinie

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(aes(colour = Species)) +
  geom_smooth(method = "lm")

Ebene 2 - Aesthetic mapping | 4

Art-spezifische Trendlinien über die Farbe (lokal)

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length)
  ) +
  geom_point(aes(colour = Species)) +
  geom_smooth(aes(colour = Species), 
    method = "lm")

Ebene 2 - Aesthetic mapping

Globale Farbwahl (für alle Geometrien)

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm")

Ebene 4 - Scales

Farbskala anpassen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B")) 

Ebene 5 - Facets

Datenpunkte aufteilen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B")) +
  facet_wrap(~Species, nrow = 2)

Ebene 6 - Coordinates

Das Koordinatensystem bspw. drehen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B")) +
  facet_wrap(~Species, nrow = 2) +
  coord_flip()

Ebene 7 - Guides

Legende und Achsenbeschriftung anpassen

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B")) +
  facet_wrap(~Species, nrow = 2) +
  coord_flip() +
  guides(colour = guide_none()) +
  labs(x = "Länge Kelchblatt (cm)",
    y = "Länge Kronblatt (cm)")

Ebene 8 - Theme

Ändern des Layouts (der Nicht-Datenelemente)

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B")) +
  facet_wrap(~Species, nrow = 2) +
  coord_flip() +
  guides(colour = guide_none()) +
  labs(x = "Länge Kelchblatt (cm)",
    y = "Länge Kronblatt (cm)") +
  theme_dark()

Zum Abschluss: speichere die Grafik

Mit ggsave()

ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length, 
    y = Petal.Length,
    colour = Species)
  ) +
  geom_point() +
  geom_smooth(method = "lm") +
  ...

ggsave("Iris_length_relationships.pdf", width = 4, height = 4)

Das letzte angezeigte Diagramm (im ‘screen device’) wird als PDF in 4x4 inch gespeichert (auch Standardeinstellung).

Zusammenfassung der einzelnen Ebenen

1. Daten

Starte mit dieser Funktion und übergebe einen Datensatz an die Funktion: ggplot(data)

2. Aesthetic mapping

Als nächstes müssen die Datenvariablen den Koordinaten zugeordnet werden damit ein leeres Koordinatensystem dargestellt wird. Dies geschieht in der aes() Funktion. Weitere visuelle Eigenschaften (sog. aesthetics) sind z.B. Größe, Farbe, Form, etc.

  • Zuordnung alleinstehend oder innerhalb von ggplot() gilt für alle Ebenen.
  • Zuordnung in geom_XXX() Funktion gilt nur für diese Ebene.

3. Geometrien

geom_XXX(): Kombiniere ein geometrisches Objekt/Grundelement, welches die Daten repräsentiert, mit den Abbildungseigenschaften, einer Statistik und einer Positionsanpassung, z.B. geom_point() oder geom_col().

4. ‘Scales’

Sog. ‘scale’ Funktionen bestimmen wie Datenwerte in visuelle Eigenschaften übersetzt werden (überschreiben die Standardeinstellungen), wie z.B.scale_fill_manual().

5. ‘Faceting’

facet_XXX() Funktionen erstellen kleinere Diagramme, die verschiedene Teilmengen der Daten anzeigen; nützlich zur Untersuchung von Interaktionen mit kategorialen Variablen.

6. Koordinatensystem

Funktionen wie coord_flip() bestimmen die Darstellung des XY-Koordinatensystems und somit die Positionierung der Daten.

7. ‘Guides’

Mit der guides() Funktion und weiteren guide_XXX() Helferfunktionen kann die Anzeige der Achsen und Legende bestimmt werden.

8. ‘Themes’

Sog. ‘theme’ Funktionen bestimmen die Anzeige aller Nicht-Datenelemente des Plots. Es können alle Einstellungen mit einem kompletten Thema wie theme_classic() überschrieben oder einzelne Einstellungen mit theme() verändert werden.

Grafik speichern

Das aktuell angezeigte ggplot Diagramm lässt sich mit ggsave() speichern: ggsave("plot.png", width = 5, height = 5) → speichert den Plot als PDF in 5x5 inch ab.

ggplots als Objekte abspeichern | 1

  • Nützlich, um weitere Ebenen später hinzuzufügen,
  • wenn der Basisplot Grundlage für mehrere Diagramme sein soll (reduziert Tipparbeit)
  • oder wenn mehrere Diagramme kombiniert werden sollen.
p1 <- ggplot(iris, 
  aes(
    x = Sepal.Length, 
    y = Petal.Length, 
    colour = Species
    ) +
  geom_point()
p1

ggplots als Objekte abspeichern | 2

  • Nützlich, um weitere Ebenen später hinzuzufügen,
  • wenn der Basisplot Grundlage für mehrere Diagramme sein soll (reduziert Tipparbeit)
  • oder wenn mehrere Diagramme kombiniert werden sollen.
p1 <- ggplot(iris, 
  aes(
    x = Sepal.Length, 
    y = Petal.Length, 
    colour = Species
    ) +
  geom_point()

p2 <- p1 +
  geom_smooth(method = "lm") +
  scale_colour_manual(values = 
    c("orange","cyan3", "#68228B"))
p2

Zurück zu unserem iris Skript

Was haben wir gerade gelernt?

# ------------------------------ Vorbereitung ----------------------------------

#### Laden von Paketen
library(tidyverse) # laedt 9 Pakete


#### Eigene Funktionen

# Variantionskoeffizient
cv <- function(x) {
  sd(x)/mean(x)
}


# -------------------- Import und Datenaufbereitung ----------------------------

#### Import von CSV-Dateien

# Import des weiten (falsch strukturierten) Datensatzes --> KLAPPT NICHT
iris <- read.csv("iris.csv", sep = ";")
iris <- read.delim("iris.csv", sep = ";", header = FALSE)

# Import des in Calc transponierten (und dann als CSV-Datei gespeicherten)
# Datensatzes --> KLAPPT
iris <- read.csv("iris_transponiert.csv")


#### Datensichtung
iris
# View(iris)
head(iris)
tail(iris)
class(iris)

nrow(iris)
ncol(iris)
dim(iris)

names(iris)
typeof(iris$Sepal.Length)
typeof(iris$Species)

# Diese Funktion fasst die obigen zusammen --> IMMER VERWENDEN!
str(iris)


#### Aufgabe aus Uebungswoche 1: Daten zuerst nach Artnamen alphabetisch
# sortieren und dann innerhalb der Arten nach Kelchblattlaenge absteigend
arrange(iris, Species, desc(Sepal.Length))


# ------------ Alternative Variante (ohne Vorbehandlung in Calc) ---------------
# --> weiten Datensatz mit Funktion aus 'readr' Paket einlesen und anpassen

#### Import
iris2 <- read_delim("iris.csv", delim = ";", col_names = FALSE)
iris2
class(iris2) # ein tibble

#### Datenaufbereitung

iris2 <- t(iris2)
class(iris2)

iris2_names <- iris2[1, ]
iris2 <- iris2[-1, ]
iris2

colnames(iris2) <- iris2_names
rownames(iris2) <- NULL

iris2 <- iris2 |>
  as.data.frame() |>
  mutate(across(Sepal.Length:Petal.Width, as.double))

# Pruefen ob die Umwandlung richtig ist
head(iris2)
str(iris2)



# ------------------- Numerische deskriptive Statistik -------------------------

#### Berechnung verschiedener Statistiken pro Variable (hier Kronblattlaenge)

# Lageparameter
mean(iris$Petal.Length)
median(iris$Petal.Length)

# Streuungsparameter
min(iris$Petal.Length)
max(iris$Petal.Length)
range(iris$Petal.Length)

var(iris$Petal.Length)
sd(iris$Petal.Length)
sd(iris$Petal.Length)/sqrt(length(iris$Petal.Length))
cv(iris$Petal.Length) # mit eigener Funktion (siehe oben)

quantile(iris$Petal.Length, probs = c(0.25, 0.5, 0.75))


#### Berechnung der Statistiken fuer mehrere Spalten -> hier in einer Schleife

# Leere Liste erstellen
meine_statistiken <- vector("list", length = 4)
names(meine_statistiken) <- names(iris)[1:4]

# for-Schleife mit 4 Iterationen (fuer Spalte 1-4 in iris)
for (i in 1:4) {

  meine_statistiken[[i]] <- c(
    Min = min(iris[[i]]),
    unteres_Quartil = quantile(iris[[i]], probs = 0.25),
    Median = median(iris[[i]]),
    Mittelwert = mean(iris[[i]]),
    oberes_Quartil = quantile(iris[[i]], probs = 0.75),
    Max = max(iris[[i]]),
    Varianz = var(iris[[i]]),
    Standardabweichung = sd(iris[[i]]),
    Standardfehler = sd(iris[[i]])/sqrt(length(iris[[i]])),
    Variationskoeffizient = cv(iris[[i]])
  )

}

meine_statistiken


#### Shortcut-Funktion: summary()
summary(iris)

# Bei Faktoren ist die summary Anzeige anders als beim Typ 'character'
iris |>
  mutate(Species = as.factor(Species)) |>
  summary()


#### Eigene (gruppierte) Statistiken fuer verschiedene Spalten mit 'tidyverse'
iris |>
  summarise(mean_sl = mean(Sepal.Length))

iris |>
  summarise(across(Sepal.Length:Petal.Width, .fns = list(mean = mean, sd = sd)))

# Statistiken gruppiert nach Species berechnen geht fast genauso
iris |>
  group_by(Species) |>
  summarise(mean_sl = mean(Sepal.Length))

iris |>
  group_by(Species) |>
  summarise(across(Sepal.Length:Petal.Width, .fns = list(mean = mean, sd = sd)))



# ------------------- Grafische deskriptive Statistik --------------------------

#### Berechnung von Mittelwert und Standardabweichung
iris_summary <- iris |>
  group_by(Species) |>
  summarise(
    PL_mean = mean(Petal.Length),
    PL_sd = sd(Petal.Length)
  ) |>
  # die Artnamen anpassen (hier Gattungsnamen anfuegen) und als Faktor speichern
  mutate(Species = factor(paste0("Iris ", Species))) |>
  # nun die Reihenfolge der Faktorstufen nach PL_mean sortieren
  mutate(Species = fct_reorder(.f = Species, .x = PL_mean, .desc = TRUE))

# Datensatz pruefen
iris_summary

# Grafik erstellen mit dem 'ggplot2' Paket (in 'tidyverse enthalten')
iris_summary |>
  ggplot(aes(x = Species, y = PL_mean)) +
  geom_col(fill = "#004586") +
  geom_errorbar((aes(ymin = PL_mean - PL_sd, ymax = PL_mean + PL_sd)),
    width = 0.2) +
  ylab("Blütenblattlänge (in cm)") +
  xlab("Schwertlilienart (Gattung Iris)") +
  theme_bw()

Zurück zu unserem Kabeljau Skript

Was haben wir gerade gelernt?

# ------------------------------ Vorbereitung ----------------------------------

#### Laden von Paketen
library(tidyverse)
# library(readODS)
# library(readxl)

#### Eigene Funktionen


# -------------------- Import und Datenaufbereitung ----------------------------

#### Import von Calc- und Excel-Dateien (ODS- und XLSX-Format)

# Import einer ODS-Datei mit dem 'readODS' Paket
kabeljau <- readODS::read_ods("DS1_W03_Streudiagramm_Kabeljau.ods",
  sheet = "Daten_Visualisierung")
str(kabeljau)

# Import einer XLSX-Datei mit z.B. dem 'readxl' Paket
kabeljau2 <- readxl::read_excel("DS1_W03_Streudiagramm_Kabeljau.xlsx",
  sheet = "Daten_Visualisierung")
str(kabeljau2)


#### Datensichtung und -transformation

# Anpassen der Spaltennamen
names(kabeljau) <- c("verzehr", "wachstum")
str(kabeljau)

# Wertebereich pruefen
summary(kabeljau)


# ---------------------- Lineare Regression: Berechnung ------------------------
# (-> Lektion L03 in DSB-02-Datenexploration mit R)

#### Manuelle Berechnung

# Um Tipparbeit zu sparen, speichern wir die Spalten als einzelne Vektoren
x <- kabeljau$verzehr
y <- kabeljau$wachstum

# Steigungsparameter b berechnen
b <- cov(x = x, y = y)/ var(x) # der shortcut mit der Kovarianz und Varianz
b

# Achsenabschnitt a berechnen
a <- mean(y) - b*mean(x)
a

# Das Bestimmtheitsmass R^2 berechnen
y_obs <- a + b*x   # die vorhergesagten Werte
ss_gesamt <- sum( (y - mean(y))^2 ) # Summenquadrate Gesamt
ss_regression <- sum( (y_obs - mean(y))^2 ) # Summenquadrate der Regression
R2 <- round(ss_regression/ss_gesamt, 4)
R2


##### Zum Vergleich die Regression automatisch berechnen mit lm()

# Erstellung des Modells
mod <- lm(formula = wachstum ~ verzehr, data = kabeljau)
mod

# Ausgabe nur der beiden Koeffizienten
coef(mod)

# Ausgabe aller wichtigen Statistiken des Modells, inklusive von R^2
# (mehr dazu in Data Science 2)
summary(mod)



# ------------------- Lineare Regression: Visualisierung  ----------------------


#### Visualisierung mit den Basisfunktionen (-> Lektion L02 und L03 in DSB-02)
# Sog. high-level Funktion plot()
plot(x = kabeljau$verzehr, y = kabeljau$wachstum,
  pch = 15, cex = 1.2, col = "#004586",
  xlab = "Verzehr/Konsum (J/g/Tag", ylab = "Wachstum (J/g/Tag")
# Sog. low-level Funktionen, die Elemente in den angezeigten Plot einfuegen
abline(a = a, b = b)
title(
  main = paste0("wachstum = ", round(a, 3), " + ", round(b, 3), "*verzehr"),
  sub = paste0("Bestimmtheitsmaß R^2 = ", R2)
)  # (paste0() verkettet Zeichen miteinander)


#### Visualisierung mit ggplot2 (-> siehe swirl-Kurs DSB-04)
kabeljau |>
  ggplot(aes(x = verzehr, y = wachstum)) + # initiert Plot
  geom_point(colour = "#004586", shape = 15, size = 3) +
  # Punktelemente hinzufuegen
  geom_abline(slope = b, intercept = a) +
  # Achsenbeschriftung anpassen und Titel hinzufuegen
  labs(x = "Verzehr/Konsum (J/g/Tag", y = "Wachstum (J/g/Tag",
    title = str_c("wachstum = ", round(a, 3), " + ", round(b, 3), "*verzehr"),
    subtitle = str_c("Bestimmtheitsmaß R^2 = ", R2)) +
  # das Layout anpassen
  theme_classic()

ggplot - geom_XXX() Funktionen

Wann wird welche Funktion benutzt?

Das ist abhängig von

  • dem was dargestellt werden soll (die Frage/Fragekategorie)
  • und den Daten-/Merkmalstypen bzw. dem Skalenniveau:

(Häufigkeits)verteilungen

Kategorial (metrisch) (1 VAR)

Code
data(bshydro15, package = "marinedata")
bshydro15 |>
  ggplot(aes(x=month)) +
  geom_bar() +
  labs(title = "geom_bar()", 
    subtitle = "Säulendiagramm (bar plot)", 
    x = "Monat", 
    y = "Häufigkeit") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Metrisch (viele Werte) (1 VARIABLE)

Code
bshydro15 |>
  ggplot(aes(x=temp)) +
  geom_histogram() +
  labs(title = "geom_histogram()", 
    subtitle = "Histogramm", 
    x = "Temperatur", y = "Häufigkeit") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Code
bshydro15 |>
  ggplot(aes(x=temp)) +
  geom_density(fill = "orange") +
  labs(title = "geom_density()", 
    subtitle = "Dichteplot (density plot)", 
    x = "Temperatur", y="Dichte") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Kategorial (metrisch) (2 VAR)

Code
bshydro15 |>
  mutate(
    fquarter = factor(lubridate::quarter(date_time)),
    fwday = factor(lubridate::wday(date_time))
  ) |>
  ggplot(aes(x=fquarter, y=fwday)) +
  geom_count() + 
  scale_size_area(max_size = 7) +
  labs(title = "geom_count()", 
    subtitle = "sog. Count Plot", 
    x="Jahresquartal", y="Wochentag") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Metrisch (viele Werte) (2 VARIABLEN)

Code
bshydro15 |>
  drop_na() |>
  ggplot(aes(x=temp, y=psal)) +
  geom_bin2d() +
  labs(title = "geom_bin2d()", 
    subtitle = "sog. Heatmap - 2d bin counts",
    x = "Temperatur", y = "Salinität") +
  scale_fill_gradient2(
    trans = "log",
    breaks = c(1, 10, 50, 250),
    guide = guide_legend(
      title = "Häufigkeit (log)")
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Code
bshydro15 |>
  ggplot(aes(x=temp, y=psal)) +
  geom_density2d(colour = "red")+
  labs(title = "geom_density2d()", 
    subtitle = "2D Dichteplot",
   x = "Temperatur", y = "Salinität") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Verteilungen - ein Gruppenvergleich

Kategorial & Metrisch (2 VARIABLEN)

Code
iris |>
  ggplot(aes(x = Species, 
    y = Sepal.Length)) +
  geom_boxplot() +
  labs(title = "geom_boxplot()", 
    subtitle = "Box-(Whisker-) Plot",
    x = "Art", y = "Sepalblattlänge") +
  theme(text = element_text(size = 15),
    axis.text = element_text(size = 10)) 

Code
iris |>
  ggplot(aes(x = Species, 
    y = Sepal.Length)) +
  geom_violin() +
  labs(title = "geom_violin()", 
    subtitle = "Violinplot",
    x = "Art", y = "Sepalblattlänge") +
  theme(text = element_text(size = 15),
    axis.text = element_text(size = 10)) 

Code
iris |>
  ggplot(aes(x = Species, 
    y = Sepal.Length)) +
  geom_jitter(width = 0.05) +
  labs(title = "geom_jitter()",
    subtitle = "sog. Stripchart",
    x = "Art", y = "Sepalblattlänge") +
  theme(text = element_text(size = 15),
    axis.text = element_text(size = 10)) 

Gruppenvergleich (von Statistiken)

Kategorial & Metrisch (2 VARIABLEN)

Code
iris |>
  group_by(Species) |>
  summarise(
    Mean = mean(Sepal.Length), 
    SD = sd(Sepal.Length)
  ) |>
  ggplot(aes(x = Species, y = Mean, 
    fill = Species)) +
    geom_col() +
    geom_errorbar(aes(ymin = Mean-SD, 
      ymax = Mean+SD), width = 0.2) +
    labs(
      title = "geom_col() und geom_errorbar()", 
      subtitle = "Säulendiagramm mit Fehlerbalken",
      x = "Art", y = "mittlere Sepalblattlänge"
    ) +
    guides(fill = "none") +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Code
iris |>
  group_by(Species) |>
  summarise(
    Mean = mean(Sepal.Length), 
    SD = sd(Sepal.Length)
  ) |>
  ggplot(aes(x = Species, y = Mean)) +
    geom_pointrange(aes(ymin = Mean-SD, 
      ymax = Mean+SD)) +
    labs(
      title = "geom_pointrange()", 
      subtitle = "sog. Point-Range-Plot",
      x = "Art", y = "mittlere Sepalblattlänge"
    ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Kategorial & Metrisch (3 VAR)

Code
CO2 |>
  group_by(Type, Treatment) |> 
  summarise(
    Mean = mean(uptake), 
    SD = sd(uptake)
  ) |>
  ggplot(aes(x = Type, y = Mean, 
    fill = Treatment)) + 
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = Mean-SD, 
    ymax = Mean+SD), width = 0.2, 
    position = position_dodge(.9)) +
  labs(
    title = "geom_col(position='dodge') und \ngeom_errorbar(position = position_dodge())", 
    subtitle = "Gruppiertes Säulendiagramm mit Fehlerbalken",
    x = "Typ", y = "mittlere CO2-Aufnahme",
    fill = "Behandlung"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10),
    plot.title = element_text(size = 12),
    plot.subtitle = element_text(size = 11)
  )

Teile-des-Ganzen / Komposition

Kategorial (& Anteil) (1 bzw. 2 VAR)

Code
data(penguins, package = "palmerpenguins")

# Version 1: den Anteil selbst berechnen
# und dann geom_col() verwenden:
# penguins |>
#   group_by(species, island) |>
#   summarise(counts = n()) |>
#   ggplot(aes(x = factor(1), y = counts,
#     fill = species)) +
#   geom_col(position = "fill", width = 1) +
#   coord_polar(theta = "y") +
#   labs(
#     title = "geom_col() und coord_polar()",
#     subtitle = "Tortendiagramm (pie chart)",
#     fill = "Pinguinart"
#   )  +
#   theme_void()

# Version 2: mit geom_bar()
penguins |>
  ggplot(aes(x = factor(1), fill = species)) +
  geom_bar(width = 1) +
  scale_fill_manual(values = c("#a16a7f", "#9ba16a", "#6a7fa1")) +
  coord_polar(theta = "y") + 
  labs(
    title = "geom_bar() und coord_polar()",
    subtitle = "Tortendiagramm (pie chart)",
    fill = "Pinguinart"
  )  +
  theme_void() +
  theme(axis.text = element_blank(),
    text = element_text(size = 13))

Kategorial (& Anteil) (2 bzw. 3 VAR)

Code
penguins |>
  group_by(species, island) |>
  summarise(counts = n()) |>
  ggplot(aes(x = island, y = counts,
    fill = species)) +
  geom_col(position = "fill") +
  scale_fill_manual(values =
      c("#a16a7f", "#9ba16a", "#6a7fa1")) +
  labs(
    title = "geom_col(position = 'fill')",
    subtitle = "Gestapeltes Säulendiagramm",
    x = "Insel", y = "Anteil der Häufigkeit",
    fill = "Pinguinart"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10))

Beziehungen zwischen Variablen

Metrisch (2 VARIABLEN)

Code
iris |>
  ggplot(aes(x = Petal.Length, 
      y = Sepal.Length)) + 
  geom_point() +
  labs(
    title = "geom_point()", 
    subtitle = "Streudiagramm (scatter plot)"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Code
iris |>
  ggplot(aes(x = Petal.Length, 
    y = Sepal.Length)) + 
  geom_point(alpha = 0.2) +
  geom_smooth() +
  labs(
    title = "geom_smooth()", 
    subtitle = "Glättungskurve"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Code
iris |>
  ggplot(aes(x = Petal.Length, 
    y = Sepal.Length)) + 
  geom_point(alpha = 0.2) +
  geom_smooth(method = "lm") +
  labs(
    title = "geom_smooth(method = 'lm')", 
    subtitle = "Regressionsgerade"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Metrisch (3 VARIABLEN X,Y,Z)

Code
iris |>
  ggplot(aes(x = Petal.Length, y = Sepal.Length)) + 
  geom_point(aes(size = Petal.Width)) +
  labs(
    title = "geom_point(aes(size=z))", 
    subtitle = "Blasenplot (bubble plot"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Metrisch (X,Y) & Kategorial (Z) (3 VARIABLEN)

Code
iris |>
  ggplot(aes(x = Petal.Length, y = Sepal.Length)) + 
  geom_point(aes(shape = Species, color = Species)) +
  labs(
    title = "geom_point(aes(shape=z, colour=z,..))", 
    subtitle = "Gruppiertes Streudiagramm"
  ) +
  theme(text = element_text(size = 13),
    axis.text = element_text(size = 10)) 

Your turn …

Quiz 1-5 | ggplots

Q1 | Häufigkeitsverteilung

ggplot(data = iris, 
  mapping = aes(x = Petal.Length)) +
  geom_histogram()

Q2 | Gruppenvergleich

ggplot(iris, 
  aes(x = Species, 
    y = Petal.Width)) +
  geom_boxplot(aes(fill = Species))

Q3 | Gruppenvergleich

ggplot(iris, 
  aes(x = Species, 
    y = Petal.Width)) +
  geom_point(alpha = 0.1, size = 5, 
    colour = 'red') 

Q4 | Beziehung

iris |>
  ggplot(aes(x = Petal.Length, y = Sepal.Length)) +
  geom_point(aes(size = Petal.Width)) 

Q5 | Beziehung

ggplot(data = mtcars, 
  aes(wt, mpg, label = rownames(mtcars))) +
  geom_point(aes(size = gear)) +
  geom_text(aes(colour = factor(cyl)), 
    hjust = 0, nudge_x = 0.05) +
  xlim(1,8)

Übungsaufgabe

Übungsskripte und Fallstudiendaten

  • Lösen Sie die Übungsskripte (in Moodle verfügbar) und
  • starten Sie mit der grafischen deskriptiven Statistik in ihrer Fallstudie!

Optionale Swirl-Lektionen zur Vertiefung

Kurs DSB-02-Datenexploration mit R

  • L02-Erste grafische Analyse
  • L04-Basisgrafik Histogramm
  • L05-Basisgrafik Boxplot
  • L06-Basisgrafik Säulendiagramm
  • L07-Basisgrafik Streudiagramm
  • L08-Globale Einstellungen und Grafiken_exportieren

Kurs DSB-04-Datenvisualisierung mit ggplot2

  • L01-Geschichtete Grammatik-Eine Einfuehrung in gglot2
  • L02-geom_Funktionen für Verteilungen kategorialer Variablen
  • L03-geom_Funktionen für Verteilungen kontinuierlicher Variablen
  • L04-geom_Funktionen für Gruppenvergleiche von Verteilungen
  • L05-geom_Funktionen für Gruppenvergleiche
  • L06-geom_Funktionen für Beziehungen
  • L07-geom_Funktionen für Trends

Challenge 1: Grafik erstellen

Versuchen Sie einen der beiden Plots mit dem iris Datensatz in base R bzw. ‘ggplot2’ zu reproduzieren:

# Weil x und y kontinuierlich sind, wird das
# Diagramm automatisch ein Streudiagramm
plot( 
  x = iris$Sepal.Length, 
  y = iris$Petal.Length, 
  col = iris$Species,
  pch = 12, 
  cex = 2, 
  xlab = "Länge Kelchblatt",
  ylab = "Länge Bütenblatt", 
  main = "Art-spezifische Beziehung beider Blattlängen"
)

library(tidyverse) # oder library(ggplot2)

ggplot(iris, 
    aes(
      x = Sepal.Length, 
      y = Petal.Length, 
      color = Species
    )
  ) +
  geom_point(shape = 11, size = 1.5) +
  labs(
    x = "Länge Kelchblatt", 
    y = "Länge Bütenblatt",
    title = "Art-spezifische Beziehung beider Blattlängen"
  ) +
  theme_classic()

Challenge 2: Grafik erstellen und abspeichern

Versuchen Sie folgenden Plot mit dem iris Datensatz in base R zu reproduzieren und diesen als PDF abzuspeichern:

pdf("MeinErstesPDF.pdf") # Erstellt eine neue PDF Datei
boxplot(
  formula = Petal.Length ~ Species, 
    # (in Boxplots werden Daten meist als Formel übergeben)
  data = iris,
  col = "yellow"
)
dev.off()  # Schließt die Datei

Wie fühlen Sie sich jetzt…?

Total konfus?


Dann schauen Sie sich doch mal…

Posit Cheatsheet

Überblick an Funktionen im ggplot2 Paket

Cheatsheet zum ggplot2 Paket frei verfügbar unter diesem Link.

Total gelangweilt?

Dann testen Sie doch Ihr Wissen in folgendem Abschlussquiz und probieren Sie diese Challenges..

Abschlussquiz

Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

Creative Commons License
Diese Arbeit is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.