2 Eén numerieke variabele visualiseren
Er bestaan verschillende manieren om de verdeling van een numerieke variabele voor te stellen. Twee voorbeelden hiervan zijn een histogram of een boxplot. Dit hoofdstuk focust op hoe je deze grafieken kan maken met ggplot2. We maken daarbij gebruik van de Palmer Penguin dataset om de verdeling van de numerieke variabele flipper_length_mm (vleugellengte) te visualiseren.
2.1 Histogram
Een eerste mogelijkheid om de verdeling van de variabele flipper_length_mm te visualiseren is een histogram. Hieronder vind je een voorbeeldhistogram dat je op het einde van dit deel ook zelf zal kunnen maken.

2.1.1 Histogram met geom_histogram()
Om een histogram te plotten, maak je gebruik van de functie geom_histogram(). Deze functie heeft één ingrediënt (aesthetic) nodig: een x-variabele (x = flipper_length_mm).
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(
data = penguins,
aes(
x = flipper_length_mm,
)
) +
geom_histogram() +
theme_minimal()`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Warning: Removed 2 rows containing non-finite outside the scale range
(`stat_bin()`).

Bij het uitvoeren van de code krijg je zowel een warning als een boodschap van ggplot. De warning verwijst naar twee ontbrekende waarden in de variabele flipper_length_mm. Dit kan je checken via summary().
Klik hier voor code
summary(penguins$flipper_length_mm) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
172.0 190.0 197.0 200.9 213.0 231.0 2
Je krijgt ook een boodschap van ggplot2, namelijk stat_bin() using bins = 30. Pick better value with binwidth. Dit verwijst naar de manier waarop geom_histogram() de breedte van de ‘bins’ bepaalt. Meer informatie daarover vind je hieronder.
2.1.2 Basisargumenten geom_histogram()
Het histogram dat je net maakte, bevat de absolute frequenties op de y-as. Als je een histogram met relatieve frequenties wil plotten, dan voeg je een tweede ingrediënt (aesthetic) toe aan de ggplot()-functie: y = after_stat(density). In het code hieronder zijn er nog enkele andere argumenten toegevoegd aan de functie geom_histogram(). Je vindt hieronder een overzicht van deze argumenten en hun betekenis:
- bin: geeft het aantal bins dat het histogram moet bevatten weer. Als je dit argument en het argument binwidth niet specificeert, dan worden er standaard 30 bins geplot. (Dat was de boodschap die
ggplot2je hierboven meegaf.)
- binwidth: geeft de breedte van de bins in het histogram weer. Als je het argument binwidth gebruikt, wordt de waarde die je bij bins ingeeft genegeerd.
- fill: opvulkleur van het histogram
- color: kleur van de lijn rondom het histogram
Laat de code hieronder lopen en bekijk het histogram. Speel vervolgens met de waarden van de argumenten bins, binwidth, fill en color en kijk wat er gebeurt.
2.1.3 Breaks op de x- en y-as specificeren
Tot nu toe bepaalde ggplot2 zelf de breaks (intervallen) op de x- en y-as. Je kan deze echter ook zelf specificeren. Daarvoor maak je gebruik van de functie scale_x_continuous() en scale_y_continuous(). Je voegt aan beide functies het argument breaks = ... toe. Op de plaats van de drie puntjes geef je dan aan welke breaks er moeten worden geplot.
De code hieronder geeft aan dat op de x-as breaks geplaatst moeten worden van de waarde 170 tot en met de waarde 230, telkens met een sprong van 10. Dit gebeurt door de drie puntjes te vervangen door seq(170, 230, 10). Op de y-as wordt er een sequentie in sprongen van 10 geplot (seq(10, 50, 10)). Aan deze sequentie wordt de waarde 57 ‘geplakt’ (met de functie c()) omdat dit de hoogst waargenomen frequentie is.
Laat de code hieronder lopen en bekijk het histogram. Specificeer zelf andere breaks en bekijk het effect ervan. (Merk op dat dit terug een histogram is dat de absolute frequentie voorstelt.)
Je hebt misschien opgemerkt dat er nog een argument is toegevoegd aan geom_histogram(): alpha = .8. Met dit argument bepaal je de transparantie van het histogram (meer specifiek van de fill-color. Standaard is de waarde voor dit argument 1 (niet-transparant). Door een waarde lager dan 1 mee te geven, verhoog je dus de transparantie van het histogram. Met de theme()-functie kan je de lay-out van de plot aanpassen. In dit geval zijn een deel van de gridlijnen (‘minor’ gridlijnen) verwijderd (panel.grid.minor = element_blank) en ook de belangrijkste gridlijnen (‘major’ gridlijnen) vertrekkend vanuit de x-as verwijderd (panel.grid.major.x = element_blank). In hoofdstuk 5 gaan we dieper in op de theme()-functie.
2.1.4 Titel, subtitel en titel van de assen toevoegen
Via de functie labs() kan je de labels van zowel de titel (title), subtitel (subtitle), als de namen van de x- en y-as aanpassen. Bedenk gepaste titels voor het histogram over de vleugellengte van de pinguïns en vul de code hieronder aan.
Aan de theme()-functie zijn twee argumenten toegevoegd om de lay-out van de tekst in de titel (plot.title = element_text(face = "bold")) en de subtitel (plot.subtitle = element_text(face = "italic")) aan te passen.
2.2 Boxplot
Een andere mogelijkheid om de verdeling van de variabele flipper-_length_mm te visualiseren is een boxplot. Een voorbeeld van een boxplot (met de data erover geplot) vind je hieronder.

2.2.1 Boxplot met geom_boxplot()
Om een boxplot te maken, gebruik je de functie geom_boxplot(). Deze functie heeft één ingrediënt (aesthetic) nodig: een x-variabele (x = flipper_length_mm) of een y-variabele (y = flipper_length_mm). Test met behulp van de code hieronder uit wat het effect is van de x in y veranderen.
2.2.2 Basisargumenten geom_boxplot()
In het staafdiagram hieronder zijn er vier argumenten toegevoegd aan de functie geom_bar():
- outliers: of er al dan niet outliers geplot moeten worden (TRUE or FALSE)
- outlier.color: bepaalt de kleur van outliers
- fill: bepaalt de opvulkleur van de boxplot
- color: bepaalt de kleur van de lijn rondom de boxplot
- alpha: bepaalt de transparantie van de box van de boxplot (niet-transparant = 1, volledig transparant = 0)
Laat de code hieronder lopen en bekijk de boxplot. Speel met de waarden van de argumenten fill, color en alpha en bekijk wat er gebeurt. (Er zijn geen outliers! Spelen met de waarde van de argumenten outliers en outlier.color heeft in dit geval dus geen zin.)
2.2.3 De x-as aanpassen
Om de breaks op de x-as aan te passen, maken we opnieuw gebruik van de functie scale_x_continuous() en het argument breaks. Specificeer dit argument in de code hieronder zodanig dat de breaks starten op 170 tot 230 lopen met sprongen van 5. Door ook het argument position = "top" aan scale_x_continuous() toe te voegen wordt de x-as bovenaan de boxplot geplaatst.
De waarden op de y-as dragen in dit geval niets meer bij. Deze zijn verwijderd door het argument axis.text.y = element_blank() toe te voegen aan de theme()-functie.
2.2.4 De data toevoegen met geom_jitter()
Een boxplot communiceert de verdeling van de variabele flipper_length_mm door enkele kengetallen samen te vatten. Dit maakt dat de onderliggende patronen in de data verborgen blijven. De onderstaande boxplots lijken identiek, maar ze verbergen een heleboel zaken. Je kan bijvoorbeeld niet aflezen hoe groot de steekproef is waarop elke boxplot gebaseerd is.

Ook de verdeling van de data zelf blijft onzichtbaar in een boxplot. Om dit op te lossen, kan je de data zelf ook toevoegen aan de boxplot. Dit kan je doen met behulp van geom_point() of geom_jitter(). Hieronder vind je een voorbeeld van beiden toegepast op de boxplot van vleugellengte.
Klik hier voor code
plot_point <- ggplot(
data = penguins,
aes(
x = flipper_length_mm
)
) +
geom_boxplot(
outliers = TRUE,
outlier.color = "darkred",
fill = "grey",
color = "black",
alpha = 0.8
) +
geom_point(
aes(y = 0),
shape = 1,
alpha = 0.3
) +
scale_x_continuous(
breaks = seq(170, 230, 10),
position = "top"
) +
labs(
x = "Vleugellengte (in mm)",
title = "Data geplot met geom_point"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold"),
axis.text.y = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank()
)
plot_jitter <- ggplot(
data = penguins,
aes(
x = flipper_length_mm
)
) +
geom_boxplot(
outliers = TRUE,
outlier.color = "darkred",
fill = "grey",
color = "black",
alpha = 0.8
) +
geom_jitter(
aes(y = 0),
height = .1,
shape = 1,
alpha = .3
) +
scale_x_continuous(
breaks = seq(170, 230, 10),
position = "top"
) +
labs(
x = "Vleugellengte (in mm)",
title = "Data geplot met geom_jitter"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold"),
axis.text.y = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank()
)
library(patchwork)
plot_point + plot_jitter +
plot_annotation(tag_levels = "1", tag_suffix = ")")Warning: Removed 2 rows containing non-finite outside the scale range
(`stat_boxplot()`).
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).
Warning: Removed 2 rows containing non-finite outside the scale range
(`stat_boxplot()`).
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Het verschil tussen beide functies is dat geom_jitter() een beetje ‘ruis’ toevoegt aan elk datapunt zodat de punten niet precies boven op elkaar geplot worden. Dat laatste is wel het geval bij het gebruik van geom_point (plot 1). Op die manier is het moeilijk in te schatten hoeveel datapunten er zijn.
Als je hierboven de code van de rechterplot bekijkt, dan merk je dat je er één aesthetic is toegevoegd aan de functie geom_jitter() (y = 0). De variabele op de x-as blijft dezelfde als in de ggplot-functie (x = flipper_length_mm). Als je de x-variabele niet had gespecificeerd, had geom_jitter() dezelfde variabele gebruikt als je hebt aangegeven in de ggplot()-functie, de variabele flipper_length_mm dus. (Alle geoms ‘erven’ de aesthetics uit de ggplot()-functie.)
Verder zijn er ook argumenten meegegeven om de hoeveelheid ‘ruis’ in verticale richting weer te geven (height = 0.1). Ook de grootte van elk datapunt (size = 1), de vorm die elk datapunt weergeeft (shape = 1) en de transparantie ervan (alpha = 0.3) is vastgelegd. In hoofdstuk 3 leer je meer over de verschillende shapes die beschikbaar zijn in R. Hieronder vind je de code terug. Speel met de verschillende waardes in de functie geom_jitter() en kijk wat er gebeurt!
Ben je benieuwd naar hoe verschillend of gelijkend de dataset achter de drie identieke boxplots is? Neem dan een kijkje op de blog van Cedric Schérer. Dit is één van de ggplot-wizards die regelmatig workshops geeft over ggplot2.
2.3 Overzicht van functies en argumenten uit hoofdstuk 2
De onderstaande functies en argumenten zijn in dit hoofdstuk aan bod gekomen:
- functie
geom_histogram()met aestheticxen de argumentenbins,binwidth,fill,colorenalpha
- functie
geom_boxplot()met aestheticsxofyen de argumentenoutliers,outlier.fill,fill,colorenalpha - functie
geom_jitter()met aestheticsxenyen de argumentenheight,size,shapeenalpha
- functies
scale_x_continuous()enscale_x_continuous()met de argumentenbreaksenposition.
- functie
labs()met de argumententitle,subtitle,xeny
Let op! De meeste functies beschikken over veel meer argumenten dan deze die in dit hoofdstuk aan bod zijn gekomen. Om hier een overzicht van te krijgen, kan je de help-functie gebruiken. Ook de specifieke aesthetics die je kan toevoegen aan elke *geom*-functie zijn uitgebreider dan je hier terug vindt. Daarover meer in de volgende hoofdstukken.