adapted from paherald.sk.ca

Überblick

In diesem Practical wirst du weiter üben mit ggplot2 schöne Grafiken zu erstellen.

Am Ende des Practicals wirst du wissen wie man:

  1. facets benutzt.
  2. themes und scales anpasst.
  3. Bilddateien erstellt.
  4. Multiple Plots verbindet.

Aufgaben

A - Setup

  1. Öffne dein TheRBootcamp R project. Es sollte die Ordner 1_Data und 2_Code enthalten.

  2. Öffne ein neues R Skript. Schreibe deinen Namen, das Datum und “PlottingII Practical” als Kommentare an den Anfang des Skripts.

## NAME
## DATUM
## PlottingII Practical
  1. Speichere das neue Skript unter dem Namen plottingII_practical.R im 2_Code Ordner.

  2. Lade tidyverse, viridis, und patchwork.

B - Lade den Datensatz

  1. Verwende die read_csv() Funktion um den Datensatz verbrechen.csv als Objekt verbrechen einzulesen. Denke an den Trick mit den Anführungszeichen.

  2. Printe den Datensatz. Wurden alle Variablentypen korrekt identifiziert?

  3. Verwende summary() um einen weiteren Überblick über die Daten zu bekommen.

C - facets

In diesem Abschnitt analysierst du den Zusammenhang zwischen dem Anteil der Bevölkerung, die mit der Metro fahren, und der Häufigkeit verschiedener Verbrechen.

  1. Verwende den folgenden Code um die Beziehung zwischen prozent_metro (x-Achse) und haeufigkeit (y-Achse) zu plotten.
ggplot(XX, aes(x = XX, 
               y = XX)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  theme_minimal()
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  theme_minimal()

  1. Sieht noch nicht so informativ aus. Ergänze scale_x_continuous(trans = 'pseudo_log') und scale_y_continuous(trans = 'pseudo_log') um die y und x-Achse zu stauchen. Später noch mehr zu Skalierungen.
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log')

  1. Besser, oder? Jetzt zeichnet sich ein schwach positiver Zusammenhang ab. Könnte das anders aussehen, wenn man die verschiedenen Klassen von Verbrechen differenziert? Versuche dies mal mit der Verwendung verschiedener Farben indem du verbrechen dem col Argument in aes() zuweist.
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit,
                       col = verbrechen)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log')

  1. Wieder nicht wirklich informativ, oder? Anstatt mit col versuche nun die verschiedenen Verbrechen mit facet_wrap() zu differenzieren. Siehe unten.
ggplot(XX, aes(x = XX, 
               y = XX)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') +
  facet_wrap(~ XX)
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit)) +
  geom_point(alpha = .2) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') +
  facet_wrap(~verbrechen)

  1. Es zeichnet sich ab, dass nicht alle Verbrechen gleich mit dem Anteil Metro-Fahrender zusammenhängen. Der stärkste Zusammenhang scheint zu Autodiebstählen und Raubüberfällen zu bestehen. Kann aber natürlich sein, dass eine dritte Variable diesen Zusammenhang treibt, z.B. der Prozentsatz unter der Armutsgrenze lebender Personen. Verwende facet_grid() um gleichzeitig nach Verbrechen und prozent_armut kleiner oder grösser 10% zu differenzieren. Wie du im Code siehst, kannst du den logischen Vergleich direkt in die Funktion schreiben.
ggplot(XX, aes(x = XX, 
               y = XX)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') +
  facet_grid(XX > 10 ~ XX)
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit)) +
  geom_point(alpha = .2) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') + 
  facet_grid(prozent_armut > 10 ~ verbrechen)

  1. Relativ eindeutig: Die Anzahl Metro-fahrender ist nur mit Verbrechen assoziiert, wenn die Bezirke eine hohe Armut aufweisen. Gleichzeitig gibt es praktisch keine Differenzierung mehr: Alle Verbrechen sind mit der Anzahl Metro-fahrender assoziert. Seltsam, oder? Vielleicht haben wir noch nicht die richtige Drittvariable. Probiere doch mal bevoelkerung_dichte grösser als 5000 als erste Variable in facet_grid() aus.
ggplot(XX, aes(x = XX, 
               y = XX)) +
  geom_point(alpha = .3) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') +
  facet_grid(XX > 5000 ~ XX)
ggplot(verbrechen, aes(x = prozent_metro, 
                       y = haeufigkeit)) +
  geom_point(alpha = .2) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') + 
  facet_grid(bevoelkerung_dichte > 5000 ~ verbrechen)

  1. Der Zusammenhang ist verschwunden. Wir haben von Beginn an übersehen, dass viele Metro-fahrer stark mit einer hohen Bevölkerungsdichte assoziert ist und diese wiederum mit der Anzahl von Delikten. Wenn du magst, exploriere die Daten ein wenig weiter. Welche Zusammenhänge kannst du noch entdecken?

D - themes

In diesem Abschnitt passt du deinen Lieblingsplot aus dem letzten Abschnitt mit der theme() Funktion an.

  1. Zuallererst speichere einen deiner Plots aus dem letzten Abschnitt als ein gg Objekt mit Namen verbrechen_gg.
verbrechen_gg <- XX
verbrechen_gg <- ggplot(verbrechen, 
                        aes(x = prozent_metro, 
                            y = haeufigkeit)) +
  geom_point(alpha = .2) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') + 
  facet_grid(bevoelkerung_dichte > 5000 ~ verbrechen)
  1. Ändere die Farbe des Hintergrunds des Panels zu "white". Verwende hierzu das panel.background in der theme() Funktion und die element_rect() Helferfunktion.
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX)
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white')
    )

  1. Als nächstes, ändere die Farbe der Haupt- und Nebenlinien zu "grey75" und deren Grössen zu .25 und .1 respektive. Verwende hierzu die Argumente panel.grid.major und panel.grid.minor und die Helferfunktion element_line().
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX),
    panel.grid.major = element_line(color = XX, size = XX),
    panel.grid.minor = element_line(color = XX, size = XX)
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1)
    )

  1. Ändere nun die Farbe des Hintergunds der Panel-Überschriften zu white. Verwende das strip.background Argument und wiederum die element_rect() Helferfunktion.
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX),
    panel.grid.major = element_line(color = XX, size = XX),
    panel.grid.minor = element_line(color = XX, size = XX),
    strip.background = element_rect(fill = XX),
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1),
    strip.background = element_rect(fill = 'white')
    )

  1. Nun ändere die Schriftart der Überschriften zu italic mit dem face Argument, setze den Text rechtsbündig (hjust = 1) und die Schriftgrösse (size) auf 12. Verwende hierzu das strip.text Argument und die genannten Argumente in element_text(). Siehe ?element_text().
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX),
    panel.grid.major = element_line(color = XX, size = XX),
    panel.grid.minor = element_line(color = XX, size = XX),
    strip.background = element_rect(fill = XX),
    strip.text = element_text(face = XX, size = XX, hjust = XX)
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1),
    strip.background = element_rect(fill = 'white'),
    strip.text = element_text(face = 'italic', size = 12, hjust = 1)
    )

  1. Setze noch die Schriftgrösse der Achsenbeschriftungen auf 12 und setze jeweils einen Abstand von 10. Verwende hierzu die Argumente axis.title.x und axis.title.y und die Helferfunktionen element_text() und margin(). Siehe ?margin().
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX),
    panel.grid.major = element_line(color = XX, size = XX),
    panel.grid.minor = element_line(color = XX, size = XX),
    strip.background = element_rect(fill = XX),
    strip.text = element_text(face = XX, size = XX, hjust = XX),
    axis.title.x = element_text(size = XX, margin = margin(t = XX)),
    axis.title.y = element_text(size = XX, margin = margin(r = XX)),
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1),
    strip.background = element_rect(fill = 'white'),
    strip.text = element_text(face = 'italic', size = 12, hjust = 1),
    axis.title.x = element_text(size = 12, margin = margin(t = 10)),
    axis.title.y = element_text(size = 12, margin = margin(r = 10))
    )

  1. Abschliessend erhöhe den Abstand zwischen den Panels auf 1.1 in der Einheit "lines" mittels des panel.spacing Argument und der unit() Funktion.
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = XX),
    panel.grid.major = element_line(color = XX, size = XX),
    panel.grid.minor = element_line(color = XX, size = XX),
    strip.background = element_rect(fill = XX),
    strip.text = element_text(face = XX, size = XX, hjust = XX),
    axis.title.x = element_text(size = XX, margin = margin(t = XX)),
    axis.title.y = element_text(size = XX, margin = margin(r = XX)),
    panel.spacing = unit(XX, units = XX)
    )
verbrechen_gg + 
  theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1),
    strip.background = element_rect(fill = 'white'),
    strip.text = element_text(face = 'italic', size = 12, hjust = 1),
    axis.title.x = element_text(size = 12, margin = margin(t = 10)),
    axis.title.y = element_text(size = 12, margin = margin(r = 10)),
    panel.spacing = unit(1.1, units = "lines")
    )

E - Mein theme() Objekt

  1. Speichere nun alle bisher genutzten theme Einstellungen in ein eigenes Objekt mit dem Namen mein_theme.
mein_theme <- theme(
  XX = XX,
  XX = XX,
  ...
  )
mein_theme <- theme(
    panel.background = element_rect(fill = 'white'),
    panel.grid.major = element_line(color = 'grey75', size = .25),
    panel.grid.minor = element_line(color = 'grey75', size = .1),
    strip.background = element_rect(fill = 'white'),
    strip.text = element_text(face = 'italic', size = 12, hjust = 1),
    axis.title.x = element_text(size = 12, margin = margin(t = 10)),
    axis.title.y = element_text(size = 12, margin = margin(r = 10)),
    panel.spacing = unit(1.1, units = "lines")
    )
  1. Jetzt kreiere einen neuen Plot mit anderen Variablen als zuvor und ergänze mein_theme (Ohne Klammern).
ggplot(verbrechen, 
       aes(x = XX, 
           y = XX)) + 
  geom_point() +
  facet_wrap(~ XX) +
  mein_theme
ggplot(verbrechen, 
       aes(x = median_einkommen, 
           y = haeufigkeit)) + 
  geom_point() +
  facet_wrap(~ staat) +
  mein_theme
  1. Wenn dir mein_theme nicht gefällt, geh zur 1. Aufgabe und nimmm Änderungen vor. Siehe ?theme. Probiere zum Beispiel mal die Argumente axis.ticks und strip.placement aus.

F - Skalierung

In diesem Abschnitt passt du die Skalierung von Achsen und Objekten an.

  1. Bevor du anfängst Skalierungen anzupassen, spezifizere zwei weitere Elemente von aes(), so damit es später mehr zu skalieren gibt. Weise im Code unten staat dem Argument col zu und bevoelkerung dem Argument size. Speichere den Plot wiederum als verbrechen_gg und plotte den Plot einmal.
verbrechen_gg <- ggplot(data = verbrechen, 
                        mapping = aes(x = prozent_metro, 
                                    y = haeufigkeit,
                                    col = XX,
                                    size = XX)) +
  geom_point(alpha = .5) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') + 
  facet_wrap(~ verbrechen) +
  mein_theme

verbrechen_gg
verbrechen_gg <- ggplot(data = verbrechen, 
                        mapping = aes(x = prozent_metro, 
                                     y = haeufigkeit,
                                     col = staat,
                                     size = bevoelkerung)) +
  geom_point(alpha = .5) +
  labs(title = "Verbrechen",
       subtitle = "Haeufigkeit und Nutzung öffentlicher Verkehrsmittel") +
  scale_x_continuous(trans = 'pseudo_log') + 
  scale_y_continuous(trans = 'pseudo_log') + 
  facet_wrap(~ verbrechen) +
  mein_theme

verbrechen_gg

  1. Als erstes verwende scale_size() und darin das range argument um die Grösse der Punkte zu verkleinern. Damit kannst du die Überlappung etwas verringern. Probiere ein paar Werte für die untere und obere Grenze aus, die jeweils kleiner als 10 sein sollten, um einen guten Trade-off zwischen Grösse und Überlappung zu finden.
verbrechen_gg + scale_size(range = c(XX, XX))
verbrechen_gg + scale_size(range = c(.5, 3))

  1. Nun ändere die Farben mit scale_color_colorblind() (spezifische Version von scale_color_gradient()), so dass die Farben auch hinsichtlich Helligkeit voneinander abgrenzbar sind.
verbrechen_gg + 
  scale_size(range = c(XX, XX)) + 
  scale_color_colorblind()
verbrechen_gg + 
  scale_size(range = c(.5, 3)) + 
  scale_color_colorblind()

  1. Alternativ kann man die Farbskala selbst setzen. Verwende scale_color_manual() und die viridis() Funktion aus dem viridis Paket (nicht vergessen zu laden) um die Farben manuell anzupassen. Viridis ist ein anderer, etablierter und schönerer Farbsatz, der ebenfalls Helligkeitsunterschiede berücksichtigt.
verbrechen_gg + 
  scale_size(range = c(XX, XX)) + 
  scale_color_manual(values = viridis(7))
verbrechen_gg +
  scale_size(range = c(.5, 3)) + 
  scale_color_manual(values = viridis(7))

  1. Ok, sieht ganz ordentlich aus, oder? Kann man aber bestimmt noch verbessern. Go explore!

G - Bilddateien

  1. Es ist an der Zeit euren Plot als eine Bilddatei zu speichern. Kreiere dafür zunächst mit dem Explorer (Windows) oder Finder (Mac) in deinem Projektordner einen neuen Ordner namens 3_Figures.

  2. Verwende nun ggsave um deinen letzten verbrechen_gg plot als eine .pdf-Datei unter dem Namen verbrechen.pdf zu speichern. Danach solltest du deinen Plot im Ordner 3_Figures finden. Schaue nach und öffne die Datei.

ggsave(filename = "3_Figures/verbrechen.pdf", 
       device = "pdf", 
       plot = verbrechen_gg,
       width = 4, 
       height = 4, 
       units = "in")
ggsave(filename = "3_Figures/verbrechen.pdf", 
       device = "pdf", 
       plot = verbrechen_gg,
       width = 4, 
       height = 4, 
       units = "in")
  1. Probiere ein paar Sachen aus:
  • Verändere width und height in der ggsave() Funktion.
  • Speichere ein .png anstatt eines .pdf indem du filename und device entsprechend anpasst.

X - Challenges: Multiple Plots

In diesem Abschnitt kombinierst du mit dem patchwork Paket (nicht vergessen zu laden) multiple Plots zu einem einzelnen Plot.

  1. Kreiere 3 verschiedene Plots, die jeweils haeufigkeiten gegen eine andere Variable im Datensatz plotten. Für eine bessere Übersicht verzichte erstmal auf facets. Nenne die 3 Plots verbrechen_a, verbrechen_b, und verbrechen_c.

  2. Stelle alle 3 Plots nebeneinander mit verbrechen_a + verbrechen_b + verbrechen_c.

  3. Stelle den 3. Plot unter die ersten beiden mit verbrechen_a + verbrechen_b / verbrechen_c.

  4. Ändere das theme aller drei Plots gleichzeitig zu theme_void() mit dem &-Operator.

  5. Speichere deinen Plot als .pdf mit ggsave().

Beispiele

library(tidyverse) 

# Scatterplot mit Hubraum und Meilen pro Gallone
ggplot(data = mpg, 
       mapping = aes(x = displ, y = hwy)) +
       geom_point()  

# Speichere den Plot
mein_plot <- ggplot(data = mpg, 
       mapping = aes(x = displ, y = hwy)) +
       geom_point()  

# Plotte den Plot
mein_plot

# Facets ------------

# Kreiere Facetten nach Klasse
mein_plot <- mein_plot + 
  facet_wrap(~class)

# plot
mein_plot

# Ändere themes ------------

# Ändere die Hintergrundfarbe
mein_plot +
  theme(
    panel.background = element_rect(fill='green')
  )

# Ändere die Rasterlinien
mein_plot +
  theme(
    panel.grid.major = element_line(color = 'red', size = 2),
    panel.grid.minor = element_line(color = 'blue', size = 1)
  )

# Ändere den Überschriftenhintergrund
mein_plot +
  theme(
    strip.background = element_rect(fill = 'blue'),
    strip.text = element_text(face = 'bold', size = 12)
  )

# Ändere die Achsenbeschriftungen
mein_plot +
  theme(
    axis.title.y = element_text(size = 12, margin = margin(r = 10)),
    axis.title.x = element_text(size = 12, margin = margin(t = 10))
  )

# Ändere die Panelabstände
mein_plot +
  theme(
    panel.spacing = unit(2, "lines")
  )

# Speichere themes ------------

# Kreiere theme
mein_theme <- theme(
  panel.background = element_rect(fill='green'),
  panel.grid.major = element_line(color = 'red', size = 2),
  panel.grid.minor = element_line(color = 'blue', size = 1),
  strip.background = element_rect(fill = 'blue'),
  strip.text = element_text(face = 'bold', size = 12),
  strip.background = element_rect(fill = 'blue'),
  strip.text = element_text(face = 'bold', size = 12),
  axis.title.y = element_text(size = 12, margin = margin(r = 10)),
  axis.title.x = element_text(size = 12, margin = margin(t = 10)),
  panel.spacing = unit(2, "lines")
)

# Wende theme an (keine Klammern)
mein_plot + mein_theme 

# Skalierung ------------

# Ändere die x-Achsenskalierung
mein_plot + scale_x_continuous(limits = c(0, 10))

# Ändere die Farbskalierung
ggplot(data = mpg, 
       mapping = aes(x = displ, y = hwy,
                     color = class)) +
       geom_point() +
  scale_color_manual(values = viridis(7))
  
# Kreiere Bilddateien ------------

# Kreiere ein pdf
ggsave(filename = "mein_plot_name", 
       plot = mein_plot,
       device = "pdf", 
       path = 'plotting_folder',
       width = 4, 
       height = 4, 
       units = "in")

Datensätze

Datei Zeilen Spalten
verbrechen.csv 7497 12

Der verbrechen Datensatz ist ein Ausschnitt aus dem “Communities and Crime Unnormalized Data Set” des “UCI Machine Learning Repository”.

Variablenbeschreibungen

Variable Beschreibung
gemeinde Name der Gemeinde
staat Kürzel des US Staats
bevoelkerung Bevölkerungs
bevoelkerung_dichte Dichte der Bevölkerungs
haushalt_groesse Durchschnittliche Haushaltsgrösse
median_einkommen Median Einkommen
prozent_pension Prozent in Pension befindlicher Einwohner
prozent_armut Prozent in Armut lebender Einwohner
prozent_arbeitslos Prozent arbeitsloser Einwohner
prozent_metro Prozent Metro-fahrender Einwohner
verbrechen Art des Verbrechen
haeufigkeit Häufigkeit des Verbrechens

Funktionen

Paket

Paket Installation
tidyverse install.packages("tidyverse")
viridis install.packages("viridis")
patchwork install.packages("patchwork")

Funktionen

facets

Function Package Description
facet_wrap() ggplot2 Kreiere Facetting mit automatischen Zeilenbrüchen
facet_grid() ggplot2 Kreiere Facetting in Tabellenform

themes

Function Package Description
theme() ggplot2 Ändere themes
element_rect() ggplot2 Helferfunktion für Flächen
element_line() ggplot2 Helferfunktion für Linien
element_text() ggplot2 Helferfunktion für Text
element_blank() ggplot2 Helferfunktion für das Entfernen von Elementen

scales

Function Package Description
scale_x_*(), scale_y_*() ggplot2 Skaliert die x- und y-Achsen
scale_size_*() ggplot2 Skaliert Grössen
scale_color_*() ggplot2 Skaliert Farben
scale_fill_*() ggplot2 Skaliert Füllfarben
scale_alpha_*() ggplot2 Skaliert Transparenz

Resourcen

Dokumentation

  • Siehe die ggplot2 Webseite.

  • Selva Prabhakaran’s Webseite mit inspirierenden ggplot2 Beispielen.

Cheatsheets


from R Studio