Skip to content
Snippets Groups Projects
ggplot-grammar.Rmd 29.27 KiB
output:
  xaringan::moon_reader:
    css: ["./styles/slides.css"]  
    nature:
      seal: false
      highlightStyle: github
      highlightLines: true
      highlightLanguage: ["r"]
      countIncrementalSlides: false
      ratio: '16:9'
      slideNumberFormat: |
        <div class="progress-bar-container">
          <div class="progress-bar" style="width: calc(%current% / %total% * 100%);">
          </div>
        </div>`
      navigation:
        scroll: false
library("knitr")
library("rmarkdown")
library("tidyverse")
library("icons")

pss <- readRDS("../datasets/pss.rds")

opts_chunk$set(#fig.path = 'pics/s6-', # path for calculated figures
               fig.align = 'center',  # alignment of figure (also possible right, left, default)
               fig.show = 'hold', # how to show figures: hold -> direct at the end of code chunk; animate: all plots in an animation
               out.width = "60%",
               echo = TRUE,     # Code is printed
               eval = FALSE,    # Code is NOT evaluated
               warning = FALSE, # warnings are NOT displayed
               message = FALSE, # messages are NOT displayed
               comment = "", # no hashtags before output
               results = "markdown",
               rows.print = 15
)

htmltools::tagList(
  xaringanExtra::use_clipboard(
    button_text = "<i class=\"fa fa-clipboard\"></i>",
    success_text = "<i class=\"fa fa-check\" style=\"color: #90BE6D\"></i>",
    error_text = "<i class=\"fa fa-times-circle\" style=\"color: #F94144\"></i>"
  ),
  rmarkdown::html_dependency_font_awesome()
)

class: center, title-slide, middle

Einführung in ggplot-Grammatik

Daten bändigen & visualisieren

B. Philipp Kleer

Methodentage 2021

11. Oktober 2021

.social[    r icons::icon_style(fontawesome("orcid"), fill=rgb(235, 129, 27, maxColorValue = 255), scale = 1)   r icons::icon_style(fontawesome("gitlab"), fill=rgb(235, 129, 27, maxColorValue = 255), scale = 1)   r icons::icon_style(fontawesome("university"), fill=rgb(235, 129, 27, maxColorValue = 255), scale = 1)   r icons::icon_style(fontawesome("researchgate"), fill=rgb(235, 129, 27, maxColorValue = 255), scale = 1) ]


Starten wir!

Nun tauchen wir in die Welt von ggplot2 ein. Das Paket ist das Grafik-Paket in R. Viele weitere Grafikpakete beruhen auf derselben Grammatik wie ggplot2, so dass Kenntnisse dieses Pakets jedem helfen.

--

Auch hier laden wir zuerst tidyverse bzw. installieren es, wenn es noch nicht installiert ist:

# install.packages("tidyverse")
library("tidyverse")

# alternativ: 
# install.packages("ggplot2")
# library("ggplot2")

--

Anschließend laden wir den Datensatz pss ins environment.

pss <- readRDS("../datasets/pss.rds") #oder eigener Pfad, wenn nicht in Cloud

ggplot

Wir machen gplot2 ist sehr umfangreich, wir machen heute einen Einstieg in die Grammatik. Da die Grafiken aber als Layer aufgebaut sind, können mithilfe des Verständnisses der Grafikgrammatik auch aufwendigere Grafiken erstellt werden.

Einen Überblick, was wir heute machen:

--

  1. Balkendiagramme und Grundaufbau von ggplot

--

  1. Histogramme

--

  1. Scatterplots

--

  1. Gruppierungen

class: inverse2, mline, center, middle

Balkendiagramme


Direkte Ausgabe

Ein Balkendiagramm ist ein Plot einer einzelnen kategorialen Variable. Mit der Funktion ggplot() kann man direkt einen Plot ausgeben.

.pull-left-40[

# direkter Output
ggplot(data = pss,
       mapping = aes(x = edu)
       )

]

--

.pull-right-60[

# direkter Output
ggplot(data = pss,
       mapping = aes(x = edu)
       )

]


Objekte speichern

Alternativ (und meist besser) ist es Grafiken in Objekte zu speichern:

--

.pull-left-40[

# oder speichern als Objekt
mfPlot <- ggplot(data = pss,
                 mapping = aes(x = edu)
                 )
mfPlot

]

--

.pull-right-60[

# oder speichern als Objekt
mfPlot <- ggplot(data = pss,
                 mapping = aes(x = edu)
                 )
mfPlot

]

--

Aber warum sind beide Plots leer?

???

nur die Struktur wurde angegeben, nicht was geplottet werden soll.


ggplot() verstehen

Wir haben nur das Grundgerüst mit der Funktion ggplot() übergeben. Diese Funktion beinhaltet immer die Daten (in data) und die Struktur des Plots (mapping). Ein Balkendiagramm ist eine univariate Darstellung und deshalb übergeben wir nur eine Variable (hier edu).

--

Um nun ein Balkendiagramm aus dem Plot zu machen, benötigen wir einen weiteren Layer, der eben ein Balkendiagramm ausgibt. Dies ist der Zusatz geom_bar().

--

.pull-left-40[

ggplot(data = pss,
       mapping = aes(x = edu)
       ) +
  geom_bar() #<<

# oder:
# mfPlot + 
#   geom_bar()

]

--

.pull-right-60[ .center[

ggplot(data = pss,
       mapping = aes(x = edu)
       ) +
  geom_bar()

# oder:
# mfPlot + 
#   geom_bar()

] ]


Prozente statt Häufigkeiten

Gerade haben wir uns Häufigkeiten ausgeben lassen. Manchmal möchte man lieber Prozente: .pull-left-40[

ggplot(data = pss, 
       mapping = aes(x = edu, 
                     y = ..prop..,  #<<
                     group = 1      #<<
                     )
       ) + 
  geom_bar()

]

--

.pull-right-60[ .center[

ggplot(data = pss, 
       mapping = aes(x = edu, 
                     y = ..prop..,  #Einstellung Prozente
                     group = 1   # Einstellung nur eine Gruppe, sonst wäre jeder Balken 100 %
                     )
       ) + 
  geom_bar()

] ]

???

Hinweise zum Code:

  1. y: Einstellung Prozente

  2. group: Einstellung nur eine Gruppe, sonst wäre jeder Balken 100 %


Nun wirklich Balken

Alternativ können wir das Diagramm auch zu einem tatsächlichen Balkendiagramm machen und die Säulen loswerden:

--

.pull-left-40[

mfPlot +
  geom_bar() +
  coord_flip()  #<<

]

--

.pull-right-60[ .center[

mfPlot +
  geom_bar() +
  coord_flip()

] ]


Bringen wir Farbe ins Spiel!

In der Regel wollen wir Grafiken ansprechend gestalten, dafür gibt es verschiedene Argumente in ggplot(). Die zwei wichtigsten sind color und fill. Probieren wir es einfach mal der Reihe nach aus. Wir wollen, dass die Balken jetzt jeweils eine andere Farbe haben.

--

.pull-left-40[

eduPlot <- ggplot(pss, 
                  aes(edu, 
                      color = edu   #<<
                      )
                  ) +
  geom_bar()
eduPlot

]

--

.pull-right-60[ .center[

eduPlot <- ggplot(pss, 
                  aes(edu, 
                      color = edu
                      )
                  ) +
  geom_bar()
eduPlot

] ]


Coloring

color macht also hier nur die Randlinie, nicht aber die Fläche der Balken farbig. Mit fill können wir das beheben.

--

.pull-left-40[

eduPlot <- ggplot(pss, 
                  aes(edu, 
                      fill = edu  #<<
                      )
                  ) +
  geom_bar()
eduPlot

]

.pull-right-60[

eduPlot <- ggplot(pss, 
                  aes(edu, 
                      fill = edu
                      )
                  ) +
  geom_bar()
eduPlot

]


Eigene Farbpaletten

Wenn man eigene Farben benennen will, kann man dies in der Unterfunktion geom_bar(). Es empfiehlt sich vorab einen Farbvektor zu definieren:

--

.pull-left-40[

cntryCol = c("steelblue", 
              "seagreen", 
              "red4", 
              "orange",
              "pink",
              "lightgray"
             )

ggplot(pss, 
       aes(x = edu, 
           fill = edu
           )
       ) +
   geom_bar(fill = cntryCol) #<< 

]

--

.pull-right-60[ .center[

cntryCol = c("steelblue", 
              "seagreen", 
              "red4", 
              "orange",
              "pink",
              "lightgray"
             )

ggplot(pss, 
       aes(x = edu, 
           fill = edu
           )
       ) +
   geom_bar(fill = cntryCol) 

] ]


Eigene Farbpaletten

Neben dieser Möglichkeit können auch Farbpaletten genutzt werden, die eine beliebige Anzahl an Farben inkludieren. Wichtig: Sind in der Farbpalette weniger Farben definiert, gibt es einen Fehler. Es müssen mindestens so viele Farben vorhanden sein, wie die Variable Kategorien hat. Hierzu fügt man einen weiteren Layer scale_fill_manual() bzw. scale_fill_color() hinzu.

--

.pull-left-40[

# a colourblind-friendly palettes
cbp1 <- c("#999999", 
          "#E69F00",
          "#56B4E9",
          "#009E73",
          "#F0E442",
          "#0072B2",
          "#D55E00",
          "#CC79A7"
          )

eduPlotCb<- ggplot(pss, 
                   aes(edu, 
                       fill = edu
                       )
                   ) + 
  geom_bar() +
  scale_fill_manual(values = cbp1)  #<<

eduPlotCb

]

--

.pull-right-60[ .center[

# a colourblind-friendly palettes
cbp1 <- c("#999999", 
          "#E69F00",
          "#56B4E9",
          "#009E73",
          "#F0E442",
          "#0072B2",
          "#D55E00",
          "#CC79A7"
          )

eduPlotCb<- ggplot(pss, 
                   aes(edu, 
                       fill = edu
                       )
                   ) + 
  geom_bar() +
  scale_fill_manual(values = cbp1)

eduPlotCb

] ]


Geld sparen

Für einen kostensparenden Druck kann man auch einfach direkt scale_fill_gray() nutzen:

--

.pull-left-40[

ggplot(pss, 
       aes(district, 
           fill = district
           )
       ) + 
  geom_bar() +
  scale_fill_grey()

]

--

.pull-right-60[ .center[

ggplot(pss, 
       aes(district, 
           fill = district
           )
       ) + 
  geom_bar() +
  scale_fill_grey()

] ]

--

Alternativ kann man auch verschiedene vorgefertigte Farbpaletten nutzen. Dazu muss man oftmals das entsprechenden Paket laden und dann gibt es eine dazugehörige Funktion, die als zusätzlicher Layer festgelegt wird.


RColorBrewer

Ein solche Paket ist zum Beispiel RColorBrewer:

--

# if(!require("RColorBrewer")) install.packages("RColorBrewer")
library("RColorBrewer")

display.brewer.all()

--

Die einzelnen Farbpaletten können, dann wie folgt hinzugefügt werden:

eduPlot +
  scale_fill_brewer(palette = "Dark2")

RColorBrewer

.center[

library("RColorBrewer")

eduPlot +
  scale_fill_brewer(palette = "Dark2")

]


Layout: Achsen anpassen

Als nächsten Schritt passen wir die Achsen an, da die Standardeinstellungen dafür meistens nicht schön sind. Hierfür gibt es folgende Funktionen:

--

  • coord_cartesian() (Achsengrenzen festlegen)

--

  • scale_x_continuous()/scale_y_continuous() (für numerische Vektoren)

--

  • scale_x_discrete()/scale_y_discrete() (für Faktoren oder Character-Variablen)

--

Was ist mit unseren Achsen?


Layout: y-Achse anpassen

.pull-left[

eduPlot2 <- eduPlot + 
  coord_cartesian(ylim = c(0,
                           1500
                           )
                  ) +
  scale_y_continuous(breaks = seq(0,  
                                  1500,  
                                  100  
                                  )  
                     )
eduPlot2

]

--

.pull-right[

eduPlot2 <- eduPlot + 
  coord_cartesian(ylim = c(0,
                           1500
                           )
                  ) +
  scale_y_continuous(breaks = seq(0,     
                                  1500,  
                                  100   
                                  )  
                     )
eduPlot2

]


Layout: x-Achse anpassen

Die x-Achse ist kategoriell und daher macht eine metrische Aufteilung keinen Sinn. Mit scale_x_discrete() können wir aber die limits festsetzen:

--

.pull-left[

eduPlot3 <- eduPlot2 + 
  scale_x_discrete(limits = c("ES-ISCED I",    
                              "ES-ISCED II",  
                              "ES-ISCED III",   
                              "ES-ISCED IV",  
                              "ES-ISCED V"  
                              )  
                   )

eduPlot3

]

.pull-right[ .center[

eduPlot3 <- eduPlot2 + 
  scale_x_discrete(limits = c("ES-ISCED I", 
                              "ES-ISCED II", 
                              "ES-ISCED III", 
                              "ES-ISCED IV",
                              "ES-ISCED V"
                              )
                   )

eduPlot3

] ]

--

Was haben wir ausgelassen?


Layout: Titel, Caption, Legende und weitere Infos

Wir können eine Reihe an Achsenbeschriftungen hinzufügen. Dies geschieht am einfachsten über die Funktion labs(). Darin gibt es folgende Unterargumente:

--

  • xlab: x-Achsentitel
  • ylab: y-Achsentitel
  • title: Titel
  • caption: Fußnote/Caption

--

eduPlot4 <- eduPlot3 +
  labs(x = "Education level",  
       y = "Frequency", 
       title = "my first shot at ggplot2",  
       caption = "Data: Panem Social Survey."  
       )  

eduPlot4

Layout: Titel, Caption, Legende und weitere Infos

.center[

eduPlot4 <- eduPlot3 +
  labs(x = "Education level",
       y = "Frequency",
       title = "my first shot at ggplot2",
       caption = "Data: Panem Social Survey."
       )

eduPlot4

]

Das schaut schon soweit gut aus, jetzt wollen wir nur noch die Legende anpassen, so dass auch dort ein angepasster Titel steht.


Layout: und wieder coloring

Dies machen wir in der Funktion scale_fill_manual(), die wir zuvor schon genutzt haben. Wir überschreiben sozusagen die Angaben:

-- .pull-left[

eduPlot5 <- eduPlot4 +
  scale_fill_manual(values = cbp1, 
                    name = "Education category", 
                    labels = c("sehr niedrig", 
                               "niedrig",  
                               "mittel", 
                               "hoch",
                               "sehr hoch"
                               )
                    )

eduPlot5

]

--

.pull-right[ .center[

eduPlot5 <- eduPlot4 +
  scale_fill_manual(values = cbp1,
                    name = "Education category",
                    labels = c("sehr niedrig",
                               "niedrig", 
                               "mittel",
                               "hoch",
                               "sehr hoch"
                               )
                    )

eduPlot5

] ]

--

Über die Funktion theme() können viele Feineinstellungen vorgenommen werden. Diese können wir nicht im einzelnen hier besprechen, aber es kann wirklich jedes Detail eingestellt werden. Mehr dazu machen die Personen, die am Nachmittag nochmal vertieft mit ggplot arbeiten.