1 Een introductie in ggplot2
1.1 ggplot2
en de tidyverse
ggplot2
is een R-package speciaal gecreëerd voor datavisualisatie. ggplot2
maakt deel uit van een grotere verzameling R-packages: de tidyverse
. De tidyverse
is een verzameling van R-pakketten dat speciaal ontworpen is om je codeeRweRk een pak intuïtiever, efficiënter en dus ook eenvoudiger te maken. Hoewel deze website zich focust op datavisualisatie met ggplot2
, introduceren we ook enkele functies uit onder meer het dplyr
-package. Dit is een pakket dat ontworpen is om datamanipulatie piece of cake te maken voor de gebruiker. Als er functies uit dplyr
worden gebruikt, dan worden deze kort toegelicht in de code zelf. Wil je een uitgebreidere introductie van dplyr
, dan vind je hier een korte tutorial. Wil je meer weten over de tidyverse
en de verschillende packages die er deel van uit maken, dan is het boek R for data science een goed vertrekpunt! Maar nu genoeg over de tidyverse
over naar ggplot2
!
1.2 De plotfuncties in R?
Wie een beetje vertrouwd is met R weet dat R verschillende plotfuncties aanbiedt. Voorbeelden daarvan zijn hist()
, boxplot()
en uiteraard ook plot()
. Hieronder vind je een voorbeeld van een histogram, een boxplot en een scatterplot gecreëerd met deze functies.
Klik hier voor code
hist(data$x, xlab = "x")
Klik hier voor code
boxplot(data$y, xlab = "y")
Klik hier voor code
plot(data$x, data$y, xlab = "x", ylab = "y")
De plot()
-functie is bijzonder omdat de output van deze functie zich aanpast aan de input die het krijgen. Geef je plot()
twee kwantitatieve variabelen mee? Dan tovert plot()
een scatterplot te voorschijn (zoals in het voorbeeld hierboven). Krijgt plot()
een tabel als input? Dan wordt er een staafdiagram gecreëerd. Er zitten dus best al wel plot-functies in R. Je vraagt je nu misschien af waarom er dan nood is aan een bijkomend R-pakket dat zich specifiek richt op visualisatie?
De plot-functies die standaard in R zitten, zijn niet zo flexibel. De functies hist()
of boxplot()
laten bijvoorbeeld alleen maar toe om een specifiek soort grafiek te creëren. Je kan wel zaken aanpassen (bv. de kleur van een histogram) of toevoegen aan de plots (bv. een titel), maar deze mogelijkheden zijn vrij beperkt en vooral niet zo intuïtief in het gebruik ervan.
1.3 Grammar of graphics
Het package ggplot2
volgt de principes van de Grammar of Graphics. De Grammar of Graphics is een ‘taal’ ontworpen door Leland Wilkinson om grafieken te creëren. Wilkinson was een Amerikaanse statisticus en expert op het gebied van data visualisatie. Hij introduceerde het concept in zijn boek “The Grammar of Graphics” (1999). Volgens de Grammar of Graphics kan elke visualisatie worden opgesplitst in dezelfde componenten (layers in Grammar of Graphics-taal). Voorbeelden van zulke layers zijn data, geometrische objecten en facetten. De Grammar of Graphics is dus een universeel systeem om visualisaties te creëren dat de basis vormt voor verschillende moderne visualisatietools (waaronder dus ook ggplot2
).
Het basisidee achter ggplot2
is dat je een plot in laagjes opbouwt. Elke laag voegt een nieuw element toe aan de plot, zoals punten, lijnen of tekst. De animatie hieronder illustreert hoe je een ggplot opbouwt aan de hand van zeven verschillende layers:
- data
- aesthetics
- geometries
- facets
- statistics
- coordinates
- themes
(Animatie overgenomen van Thomas de Beus)
Een visualisatie maken in ggplot2
doe je dus laagje per laagje, een beetje zoals je een cake bakt. Op de figuur hieronder zie je hoe elk onderdeel van de cake overeenkomt met een layer in ggplot2
.
(Figuur overgenomen van Tanya Shapiro)
Als je een cake bakt, start je met het leggen van de basis. In ggplot2
doe je dat met de functie ggplot()
. Elke visualisatie start dus met deze functie. Vervolgens specificeer je de ingrediënten met behulp van de aesthetics en de smaken met scales. Dan voeg je laagjes toe aan je cake in de vorm van geoms. Ten slotte kan je de cake naar eigen believen afwerken door middel van de functie theme
. Genoeg gepraat over het maken van visualisaties, tijd om zelf aan de slag te gaan!
1.4 ggplot2
in een notendop
Om zelf een visualisatie te maken, hebben we uiteraard data nodig. Een leuke dataset om mee aan de slag te gaan, is de Palmer Penguin data. Deze dataset is afkomstig van onderzoek uitgevoerd door Kristen Gorman op het Palmer Station (Antarctica). De data bevat metingen en observaties over drie pinguïnsoorten (Adélie, Kinband en Gentoo) verzameld in 2007, 2008 en 2009:
- snavellengte (
bill_length_mm
)
- snaveldiepte (
bill_depth_mm
)
- vleugellengte (
flipper_length_mm
)
- lichaamsgewicht (
body_mass_g
)
- geslacht (
sex
)
- soort (
species
)
- kolonielocatie (
island
)
- jaar van observatie (
year
) Meer info over de Palmer Penguins data vind je hier.
Om met de pinguïndata aan de slag te gaan, dien je eerst de packages tidyverse
en palmerpenguins
te installeren en laden. Vervolgens kan je de data zelf in RStudio laden via de functie data
.
Klik hier voor code
install.packages("tidyverse")
install.packages("palmerpenguins")
library(tidyverse)
library(palmerpenguins)
data("penguins")
Bekijk vervolgens 10 random rijen uit de dataset met behulp van de functie slice_sample()
(functie uit dplyr
).
Klik hier voor code
# Sample 10 random rijden (n = 10) uit de data `penguins`
slice_sample(penguins, n = 10)
# A tibble: 10 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Gentoo Biscoe 44.9 13.8 212 4750
2 Adelie Biscoe 35.7 16.9 185 3150
3 Gentoo Biscoe 50.4 15.7 222 5750
4 Chinstrap Dream 58 17.8 181 3700
5 Adelie Biscoe 40.6 18.6 183 3550
6 Adelie Torgers… 36.2 17.2 187 3150
7 Gentoo Biscoe 45.1 14.4 210 4400
8 Adelie Biscoe 39.6 17.7 186 3500
9 Chinstrap Dream 45.2 16.6 191 3250
10 Gentoo Biscoe 44.9 13.3 213 5100
# ℹ 2 more variables: sex <fct>, year <int>
Check via glimpse()
ook welke variabelen allemaal in de dataset zitten en hoe deze gedefineerd zijn (als factor, …).
Klik hier voor code
glimpse(penguins)
Rows: 344
Columns: 8
$ species <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
$ island <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
$ bill_length_mm <dbl> 39.1, 39.5, 40.3, NA, 36.7, 39.3, 38.9, 39.2, 34.1, …
$ bill_depth_mm <dbl> 18.7, 17.4, 18.0, NA, 19.3, 20.6, 17.8, 19.6, 18.1, …
$ flipper_length_mm <int> 181, 186, 195, NA, 193, 190, 181, 195, 193, 190, 186…
$ body_mass_g <int> 3750, 3800, 3250, NA, 3450, 3650, 3625, 4675, 3475, …
$ sex <fct> male, female, female, NA, female, male, female, male…
$ year <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…
Nu je een beetje vertrouwd bent met de data kunnen we aan de slag met ggplot2
.
1.4.1 Data en aesthetics
Je start in ggplot2
steeds met de functie ggplot()
. In deze functie geef je aan welke data je wil gebruiken (data = penguins
) en je specificeert ook de aesthetics. De aesthetics vormen de ingrediënten van je plot. Het zijn m.a.w. de variabelen die je wil plotten. De aesthetics specificeren doe je aan de hand van de functie aes()
. In dit geval willen we de variabele flipper_length_mm
op de x-as en de variabele body_mass_g
op de y-as.
Kopieer de code hieronder naar RStudio op je eigen laptop en probeer deze uit. Zorg dat de packages tidyverse
en palmerpenguins
geladen zijn. Door hieronder op ‘Plot’ te klikken, vind je het verwachte resultaat terug.
Klik hier voor code
<- ggplot(
Plot
## Stap 1: data
data = penguins,
## Stap 2: aesthetics specificeren (mapping)
aes(
x = flipper_length_mm,
y = body_mass_g)
)
Plot
1.4.2 Geometries
De vorige code levert een lege plot op! Dit komt omdat je alleen de basis voor je plot hebt gelegd (met de functie ggplot()
), maar niet hebt aangegeven welk geometrisch object (geom in ggplot2
-taal) je wilt gebruiken. Een geom representeert de visuele elementen die worden gebruikt om gegevens weer te geven in de plot. Elke geom komt overeen met een specifiek type grafische representatie, zoals punten, lijnen, balken of gebieden. Geoms bepalen dus hoe de gegevens visueel worden weergegeven. In ons voorbeeld voegen we de geom_point()
functie toe. Deze functie geeft elk datapunt weer als een punt op de plot? Vul je code aan en evalueer het resultaat. Je krijgt een warning. Wat betekent deze warning?
Kopieer de code hieronder naar RStudio op je eigen laptop en probeer deze uit. Door hieronder op ‘Plot’ te klikken, vind je het verwachte resultaat terug.
Klik hier voor code
<- ggplot(
Plot
## Stap 1: data
data = penguins,
## Stap 2: aesthetics specificeren (mapping)
aes(
x = flipper_length_mm,
y = body_mass_g)
+
) ## Stap 3: voeg geometry toe
geom_point()
Plot
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).
De warning wijst erop dat er twee ontbrekende observaties zijn (en dat deze uiteraard niet geplot zijn).
1.4.3 Facets
Stel dat we het verband tussen het lichaamsgewicht en vleugellengte per pinguïnsoort willen plotten. We willen m.a.w een aparte scatterplot per soort (small multiples). Dit kan je heel eenvoudig realiseren met behulp van de functie facet_wrap()
. Tussen de haakjes geef je aan op basis van welke variabele de facets moeten worden gecreëerd (in dit geval species
). Deze variabele dient vooraf gegaan te worden door een tilde (~
).
Kopieer de code hieronder naar RStudio op je eigen laptop en probeer deze uit. Door hieronder op ‘Plot’ te klikken, vind je het verwachte resultaat terug.
Klik hier voor code
<- ggplot(
Plot
## Stap 1: data
data = penguins,
## Stap 2: aesthetics specificeren (mapping)
aes(
x = flipper_length_mm,
y = body_mass_g)
+
) ## Stap 3: voeg geometry toe
geom_point() +
## Stap 4: definieer facets
facet_wrap(~species)
Plot
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).
1.4.4 Theme
In een laatste stap passen we het plot-thema aan. Als je geen plot-thema meegeeft, dan gebruikt deze het default plot-thema. Dit plot-thema heeft echter een grijze achtergrond die verder niets bijdraagt aan de plot (chart junk!). Verander daarom het plot-thema naar theme_minimal()
. Voeg dit plot-thema standaard toe aan alle plots die je creëert!
Kopieer de code hieronder naar RStudio op je eigen laptop en probeer deze uit. Door hieronder op ‘Plot’ te klikken, vind je het verwachte resultaat terug.
Klik hier voor code
<- ggplot(
Plot
## Stap 1: data
data = penguins,
## Stap 2: aesthetics specificeren (mapping)
aes(
x = flipper_length_mm,
y = body_mass_g)
+
) ## Stap 3: voeg geometry toe
geom_point() +
## Stap 4: definieer facets
facet_wrap(~species) +
## Stap 5: pas thema aan
theme_minimal()
Plot
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).
1.4.5 Plot opbouwen
Je bouwde net je allereerste visualisatie in ggplot2
laagje voor laagje op! Uiteraard kan je nog veel meer zaken toevoegen. Hieronder vind je een uitgebreider voorbeeld terug.
We leggen stap per stap uit wat er precies wordt toegevoegd aan de plot. Daarbij wordt ook de nodige code meegegeven. Je zal merken dat er in de code gebruik gemaakt wordt van functies uit dplyr
(het datamanipulatie pakket uit de tidyverse). Je vindt twee manieren terug om code aan elkaar te rijgen. In ggplot2
gebeurt dit met een +
. dplyr
maakt echter gebruik van de pipe (%>%
).
- De basis van de plot wordt gelegd met de functie
ggplot()
. Er wordt aangegeven dat de variabeleflipper_length_mm
op de x-as dient te komen en de variabelebody_mass_g
op de y-as. De plot wordt weggeschreven naar een object met de naam ‘P1’.
Klik hier voor code
<-
P1 ## Gebruik de dataset penguins
%>%
penguins ## Gebruik alleen rijen waarin sex NIET NA is
filter(!is.na(sex)) %>%
ggplot(aes(x = flipper_length_mm, y = body_mass_g ))
- Er wordt een geom toegevoegd aan de plot P1 (
geom_point()
).
Klik hier voor code
<-
P2 +
P1 geom_point()
- Om de datapunten een andere vorm en kleur te geven naar geslacht, worden in
geom_point()
nieuwe ingrediënten (aesthetics) toegevoegd d.m.v.aes(color = sex, shape = sex)
. Omdat de datapunten soms overlappen, wordt er transparantie toegevoegd aan de punten (alpha = .8
) en ook de grootte van de punten wordt aangepast (size = 3
). Tenslotte wordt er ook aangegeven welke kleuren er gebruikt dienen te worden viascale_color_manual(values = c("darkorange", "purple"))
.
Klik hier voor code
<-
P3 +
P2 geom_point(
aes(color = sex, shape = sex),
alpha = .8,
size = 3
+
) scale_color_manual(
values = c("darkorange","purple")
)
- In de vierde stap wordt een trendlijn toegevoegd aan de plot. Hiervoor wordt een tweede geom gebruikt:
geom_smooth()
. Met het argumentmethod = "lm"
geven we aan dat we een lineaire trendlijn willen.
Klik hier voor code
<- P3 + geom_smooth(method = "lm") P4
- We willen graag een aparte trendlijn voor de mannelijke en vrouwelijke pinguïns. Dit wordt aangegeven door
aes(color = sex)
toe te voegen aan de functiegeom_smooth()
. Het argumentse = F
geeft aan dat we GEEN betrouwbaarheidsinterval rond de trendlijnen willen.
Klik hier voor code
<- P3 +
P5 geom_smooth(
aes(color = sex),
se = F,
method = "lm"
)
- De labels van de x- en y-as krijgen een andere naam via de functies
scale_x_continuous()
enscale_y_continuous()
.
Klik hier voor code
<-
P6 +
P5 scale_x_continuous("Flipper length (mm)") +
scale_y_continuous("Body Mass (g)")
- In de zevende stap wordt het plot-thema aangepast naar
theme_minimal()
.
Klik hier voor code
<- P6 + theme_minimal() P7
- De laatste stap bestaat uit het toevoegen van een titel en subtitel. Hiervoor wordt de
labs()
-functie gebruikt (via de argumententitle
ensubtitle
.
Klik hier voor code
<- P7 +
P8 labs(
title = "Palmer penguins",
subtitle = "Flipper length and body mass for both sexes"
)
Na deze korte introductie duiken we verder de wereld van ggplot2
in.