Scales, akser, legends (guides)

I ggplot2 findes automatiske funktioner, der optimerer skalaer for x-akse, y-akse, color, fill og signaturforklaringer (eng. figure legends). Ved at justere skalaer kan vi ændre udseendet af x-aksen og y-aksen. Skalaer bruges også til at ændre indholdet i signaturforklaringer. Det betyder, at skalaer bruges til at ændre både akser og signaturforklaringer. Tilsammen kaldes akserne og signaturforklaringerne for figurens guides.

I dette kapitel vil vi bruge data fra undersøgelsen mpg. Sørg for, at tidyverse er aktiveret, hvilket bevirker, at også ggplot2 og mpg er aktiveret:

library(tidyverse)

## Inspicér de første 5 rækker i mpg
head(mpg)
manufacturer <chr> model <chr> displ <dbl> year <int> cyl <int> trans <chr> drv <chr> cty <int> hwy <int> fl <chr>
audi a4 1.8 1999 4 auto(l5) f 18 29 p
audi a4 1.8 1999 4 manual(m5) f 21 29 p
audi a4 2.0 2008 4 manual(m6) f 20 31 p
audi a4 2.0 2008 4 auto(av) f 21 30 p
audi a4 2.8 1999 6 auto(l5) f 16 26 p
audi a4 2.8 1999 6 manual(m5) f 18 26 p

mpg-data.

I følgende eksempel oprettes en graf med x-akse, y-akse og farvekodning (color) baseret på kolonnen class:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point()
Punktdiagram af motorvolumen (displ) mod brændstofforbrug på motorvej (hwy) i mpg, farvet efter bilklasse (class)

Af ovenstående graf fremgår det, at ggplot() automatisk har oprettet en skala for x-aksen, y-aksen og en skala for farverne på datapunkterne. Det gør ggplot() med funktionerne scale_x_continuous(), scale_y_continuous() og scale_colour_discrete(). Vi behøver ikke at angive disse funktioner i koden ovenfor, fordi ggplot() gør det automatisk. Hvis vi tilføjer disse funktioner, får vi en identisk graf:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_x_continuous() +
  scale_y_continuous() +
  scale_colour_discrete()
Samme punktdiagram af displ mod hwy farvet efter bilklasse, tegnet med eksplicit angivne standardskalaer

Disse funktioner og deres navne fortolkes som følger:

Funktion Forklaring
scale_x_continuous() Ændrer en kontinuert (numerisk) x-akse. I ovenstående eksempel ændres skalaen for displ.
scale_x_continuous() Ændrer en kontinuert (numerisk) y-akse. I ovenstående eksempel ændres skalaen for hwy.
scale_colour_discrete Ændrer et colour (color) argument, der er en diskret variabel. I ovenstående eksempel ændres skalaen for class.

Andre scale-funktioner bruges på samme måde og følger samme princip for navngivning:

  • Hvis x-aksen er en numerisk variabel, justeres den med scale_x_continuous().
  • Hvis y-aksen er en numerisk variabel, justeres den med scale_y_continuous().
  • Hvis x-aksen er en kategorisk variabel, justeres den med scale_x_discrete().
  • Hvis y-aksen er en kategorisk variabel, justeres den med scale_y_discrete().
  • Hvis color er en kategorisk variabel, justeres den med scale_color_continuous().
  • Hvis color er en kategorisk variabel, justeres den med scale_color_discrete().

Guides: akser og legends

Figurens guides (da. guider) består af aksernes (x, y) skala og signaturforklaringerne. Akser og signaturforklaringer (legends) ændres med følgende argumenter:

  • breaks: ændrer, hvilke tal der vises på en akse, henholdsvis hvilke kategorier der vises i en signaturforklaring.
  • labels: ændrer de labels, der vises på en akse eller i en signaturforklaring.
  • limits: ændrer aksernes interval.

Akser (x, y)

Vi fortsætter med den foregående graf, hvor vi nu fjerner x-aksens og y-aksens skala. Det gøres ved at angive breaks=NULL, som følger:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_x_continuous(breaks = NULL) +
  scale_y_continuous(breaks = NULL)
Punktdiagram af displ mod hwy, hvor skalamarkeringer, skalaværdier og gitterlinjer på x- og y-aksen er fjernet

I den første figur så vi, at x-aksen går fra 2 til 7 med intervaller på 1,0. Vi ændrer skalaen, så den går fra 2 til 7 med med intervaller på 0,5. Det gøres ved, at breaks får en sekvens (med funktionen seq()) fra 2 til 7 med 0,5 mellemrum, som følger:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_x_continuous(breaks = seq(from=2, to=7, by=0.5))
Punktdiagram af displ mod hwy, hvor x-aksen har brudpunkter med 0,5 enheders mellemrum fra 2,0 til 7,0

I næste eksempel ændrer vi det, så x-aksens grænse udvides fra 0 til 15:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_x_continuous(breaks = seq(from=2, to=7, by=.5),
                     limits = c(0, 10))
Punktdiagram af displ mod hwy, hvor x-aksens grænser er udvidet, så punkterne samles midt i figuren

I næste eksempel begrænser vi x-aksen til intervallet 1 til 5, og vi erstatter tallene med nye labels, nemlig de første fem bogstaver:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_x_continuous(breaks = seq(1, 5, by=1),
                     limits = c(1, 5),
                     labels = c("A", "B", "C", "D", "E"))
Punktdiagram af displ mod hwy, hvor x-aksens skalaværdier er erstattet med etiketterne A til E

Signaturforklaringer (legends)

Som nævnt ovenfor har breaks og limits også effekt på signaturforklaringer. Selve signaturforklaringen oprettes ud fra den æstetiske mapping. I nedenstående eksempel bruges color=class i aes(). For at ændre denne skala bruger vi funktionen scale_color_discrete(). Vi angiver, at breaks kun indeholder "pickup", og den får etiketten "Pickup car".

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_color_discrete(breaks=c("pickup"),
                       labels=c("Pickup car"))
Punktdiagram af displ mod hwy farvet efter bilklasse, hvor signaturforklaringen kun viser én klasse med etiketten Pickup car

På den måde kan også rækkefølgen i signaturforklaringen justeres.

Placering af signaturforklaring (figur legends)

Placeringen af signaturforklaringen påvirker ikke de data, der præsenteres i grafen. Sådanne komponenter justeres med theme(). Signaturforklaringen kan placeres hvor som helst i figuren. Nedenfor følger flere eksempler med justeringer af forklaringens placering.

I det første eksempel fjerner vi signaturforklaringen med argumentet legend.position = "none".

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  theme(legend.position = "none")
Punktdiagram af displ mod hwy farvet efter bilklasse, hvor signaturforklaringen er fjernet helt

Argumentet legend.position accepterer også specifikationerne "bottom", "top", "right", "left". Det demonstreres nu med "bottom" som valg:

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  theme(legend.position = "bottom")
Punktdiagram af displ mod hwy farvet efter bilklasse med signaturforklaringen placeret under diagrammet i to rækker

Andre alternative placeringer med tekststrenge følger:

  • theme(legend.position = "top")
  • theme(legend.position = "bottom")
  • theme(legend.position = "left")
  • theme(legend.position = "right")

Du kan også placere legends med koordinater, hvor både x- og y-aksen går fra 0 til 1. For at få legends placeret nederst til højre er koordinaterne x=1 og y=0, hvilket angives i en numerisk vektor (c(1, 1)).

Du kan også placere legends med koordinater, hvor både x- og y-aksen går fra 0 til 1. For at få legends placeret øverst til højre er koordinaterne x=1 og y=1, hvilket angives i en numerisk vektor (c(1, 1)). I theme() har legend yderligere argumenter (legend.justification, legend.margin osv.), som vi også vil bruge nedenfor for at optimere placeringen af legend. I koden følger kommentarer, der forklarer, hvad hvert argument gør.

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  theme(
    # Legend placeres øverst til højre
    legend.position = c(1, 1),

    # Legend får ikke lov at gå uden for grafens grænser
    legend.justification = c("right", "top"),

    # Margin skaber en margen mellem legend og dens omgivelser.
    # 10 mm margin bruges på alle 4 kanter
    legend.margin = margin(10, 10, 10, 10),

    # Baggrunden fjernes ved at angive den som et tomt element
    legend.background = element_blank())
Punktdiagram af displ mod hwy med signaturforklaringen placeret inde i diagrammets øverste højre hjørne
Med guides() er det muligt at justere enkelte legends i en figur. Lad os justere placeringen og udseendet af legends for bilproducenter (manufacturer) ovenfor. Det gør vi ved at ændre antallet af rækker (nrow), som legends præsenteres på, samt størrelsen (size) på formerne i legends.
ggplot(mpg, aes(x=displ,
                y=hwy,
                color=manufacturer,
                shape=drv)) +
  geom_point(size=3) +

  # Placér legends over grafen
  theme(legend.position = "top") +

  # Ændrer enkelte legends
  guides(colour = guide_legend(nrow = 3, #antal rækker
                               override.aes = list(size = 4), # størrelse på forklaringerne
                               order = 2), # rækkefølgen
         shape = guide_legend(nrow = 3,
                              override.aes = list(size = 4),
                              order = 1))
Punktdiagram af displ mod hwy med farve efter producent og form efter drivlinje, signaturforklaringer øverst i tre rækker

Vi kan bruge guides() til at skjule en enkelt legend. Nedenfor skjuler vi legends for shapes, og vi skifter label for legend for color til "Biltillverkare".

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=manufacturer,
                shape=drv)) +
  geom_point() +
  theme(legend.position = "top") +
  guides(colour = guide_legend(title="Biltillverkare",
                               nrow = 3,
                               override.aes = list(size = 5)),
         # Skjul legend for shape
         shape = "none")
Punktdiagram af displ mod hwy, hvor kun signaturforklaringen for producent vises, med overskriften Biltillverkare og større symboler

Erstatte eller transformere en skala

En numerisk skala kan transformeres for tydeligere at anskueliggøre sammenhænge i data. I næste eksempel bruger vi data fra gapminder til at visualisere, hvordan befolkningsstørrelse (pop) og forventet levetid (lifeExp) korrelerer. Vi gør det med og uden logaritmering af akserne. For at placere figurerne ved siden af hinanden sender vi ggplot()-objekterne til to nye objekter (plot_1, plot_2), som vi derefter bruger i plot_grid() fra pakken cowplot.

library(gapminder)

## Uden logaritme
plot_1 <- ggplot(gapminder, aes(x=pop,
                                y=lifeExp,
                                color=year)) +
  geom_point() +
  labs(title="Utan logaritmerade axlar") +
  theme(legend.position = "bottom")

## Med logaritme
plot_2 <- ggplot(gapminder, aes(x=pop,
                                y=lifeExp,
                                color=year)) +
  geom_point() +
  scale_x_log10() +
  scale_y_log10() +
  labs(title="Med logaritmerade axlar") +
  theme(legend.position = "bottom")

library(cowplot)
plot_grid(plot_1, plot_2)
To punktdiagrammer af befolkning mod forventet levetid i gapminder, henholdsvis uden og med logaritmiske akser

Ændre farveskala og farvepalet

R Colorbrewer

Scale bruges også til at farve diskrete variabler. I ggplot findes indbyggede farvepaletter, hvor farverne er valgt med omhu. Derudover findes andre farvepaletter med mere specifikke formål. For eksempel findes R ColorBrewer, som består af en række farvepaletter, der er særligt egnede til farveblinde. For at se alle farvepaletterne i R ColorBrewer skriver du følgende kommando:

RColorBrewer::display.brewer.all()
Oversigt over alle ColorBrewer-paletter i R: sekventielle, kvalitative og divergerende farveskalaer

Du kan bruge disse farvepaletter i ggplot med funktionen scale_color_brewer(). Som det fremgår af ovenstående figur, findes der en farvepalet, der hedder "Set3". Nedenfor bruger vi "Set3" i scale_color_brewer().

ggplot(mpg, aes(x=displ,
                y=hwy,
                color=class)) +
  geom_point() +
  scale_color_brewer(palette = "Set1")
Punktdiagram af displ mod hwy, hvor bilklasserne er farvet med en kvalitativ ColorBrewer-palet

På https://colorbrewer2.org/ kan du læse mere om ColorBrewer.

Viridis

I pakken viridis findes scale_color_viridis() og scale_fill_viridis(), som kan bruges både til kontinuerte og diskrete variabler. Til kontinuerte variabler er viridis at foretrække frem for ColorBrewer.

library(viridis)

## Viridis standardfarver
ggplot(gapminder, aes(x=pop,
                      y=lifeExp,
                      color=year)) +
  geom_point() +
  scale_color_viridis_c()

## Viridis plasma
ggplot(gapminder, aes(x=pop,
                      y=lifeExp,
                      color=year)) +
  geom_point() +
  scale_color_viridis_c(option = "plasma")
Punktdiagram af befolkning mod forventet levetid, hvor punkterne farves efter år med den kontinuerte viridis-skala
Punktdiagram af befolkning mod forventet levetid, hvor punkterne farves efter år med viridis-paletten plasma

Manuelle farveskalaer

Hvis de indbyggede farvepaletter og paletter i pakker som for eksempel viridis ikke passer, kan du oprette farvepaletten manuelt. Det gøres med scale_colour_manual() eller scale_fill_manual(). Her følger et eksempel, hvor scale_colour_manual() bruges til manuelt at oprette farver til biler baseret på class.

ggplot(gapminder, aes(x=pop,
                y=lifeExp,
                color=continent)) +
  geom_point() +
    scale_colour_manual(values = c(Africa="darkblue",
                                   Asia="pink",
                                   Europe="green",
                                   Oceania="purple",
                                   Americas="cyan"))
Punktdiagram af befolkning mod forventet levetid med manuelt valgte farver for hvert kontinent

Med funktionerne scale_fill_gradient2() og scale_colour_gradient2() kan kontinuerte variabler få en farvegradient med et midtpunkt. I eksemplet nedenfor bruges scale_colour_gradient2() til at farve datapunkter efter år 1980 med sorte punkter og datapunkter før 1980 med gule punkter, med en gradient fra 1980 i begge tilfælde. Bemærk, at også akserne er logaritmiske.

ggplot(gapminder, aes(x=pop,
                      y=lifeExp,
                      color=year)) +
  geom_point() +
  scale_colour_gradient2(midpoint=1980,
                         high = "black",
                         low = "gold") +
  scale_x_log10() +
  scale_y_log10()
Punktdiagram af befolkning (logaritmisk) mod forventet levetid med en tretrins farvegradient efter år, gul via hvid til sort