Farbpaletten für nominale Variablen

1 Setup

library(tidyverse)
library(paletteer)
library(scales)  # show_col()
library(colorblindr)  # from github
library(ggthemes)

Das Paket paletteer trägt eine große Auswahl an Farbpaletten zusammen und erleichtert die Handhabung in R.

2 tl;dr

Die Farbpalette von Okabe und Ito ist eine gute Wahl, um eine nominale Variable in Farben zu kodieren.

paletteer_d("colorblindr::OkabeIto")
#> <colors>
#> #E69F00FF #56B4E9FF #009E73FF #F0E442FF #0072B2FF #D55E00FF #CC79A7FF #999999FF

Mehr Details weiter unten.

3 Beispiel für Farbwahl bei einer nominaler Variablen

Hier ist ein Beispiel für Farbwahl bei nominal skalierten Variablen:

ggplot(iris) +
  aes(x = Species, y = Sepal.Width) +
  geom_boxplot(aes(fill = Species))

4 Anforderungen an eine Farbpalette (für nominale Variablen)

Hier sind einige (der wichtigsten) Anforderungen an eine Farbpalette für nominal skalierte Variablen:

  1. optisch klar unterscheidbare Farben
  2. visuelle Gleichabständigkeit der Farben
  3. Robust bei Farb-Sehschwächen
  4. Robust bei Schwarz-Weiß-Druck
  5. gut benennbare Farben (“grün” und “gelb”)
  6. gleich starke Farben (z.B. kann ein sanftes Grau wie eine Abschwächung der Bedeutung wirken)
  7. nicht zu hell, damit sie auf weißem Hintergrund erkennbar sind

5 Auswahl

Hier ist eine Auswahl an Farben, z.B. von Wes Andersons Blog, vermittelt durch das R-Paket wesanderson.

wesanderson::wes_palette("FantasticFox1")

Die Farbauswahl ist nett, aber ich fand keine Hinweise, ob die Farbpaletten geprüft sind auf alle unsere Anforderungen.

6 Hilfsfunktion

Schreiben wir uns eine Hilfsfunktion, um die Farben einer Palette großflächig zu zeigen.

show_cols <- function(col_pal, n = 5){
d <- tibble(x = 1:length(col_pal[1:n]),
            col = factor(col_pal[1:n], levels = col_pal[1:n]))

ggplot(d) +
  aes(x=x)+
  geom_bar(aes(fill = col)) +
  theme_void() +
  scale_fill_manual(values = col_pal)
}
paletteer_d("awtools::a_palette")
#> <colors>
#> #2A363BFF #019875FF #99B898FF #FECEA8FF #FF847CFF #E84A5FFF #C0392BFF #96281BFF
paletteer_d("awtools::a_palette") %>% show_cols()

Ah, es gibt auch eine Plot-Methode, die den Job erledigt :-)

paletteer_d("awtools::a_palette", n = 5) %>% plot()

Allerdings ohne die RGB-Werte auszugeben.

7 AWTools

Ähnliches wie für Wes Andersons Farben gilt für Austin Wehrweins Paletten, vermittelt über das Paket awtools.

paletteer_d("awtools::mpalette", n = 5)
#> <colors>
#> #017A4AFF #FFCE4EFF #3D98D3FF #FF363CFF #7559A2FF
paletteer_d("awtools::mpalette", n = 5) %>% show_cols()

8 ggthemes

Auch das Paket `ggthemes stellt eine nette Auswahl vor.

show_cols(paletteer_d("ggthemes::colorblind", n = 5))

Schwarz sticht hier hervor; die anderen Farben sind dezent, das Schwarz ist, anders, naja, schwarz!

9 Weitere Paletten

Paletteer stellt noch weitere Paletten bereit, wie z.B. diese hier

paletteer_d(`"beyonce::X18"`)
#> <colors>
#> #424395FF #018AC4FF #5EC2DAFF #EBC915FF #EB549AFF #550133FF
paletteer_d(`"beyonce::X18"`) %>% show_cols()

10 rtist

Visuell ansprechend (nach meiner Meinung) sind auch die Paletten von rtist:

paletteer_d(`"rtist::picasso"`, n = 5) %>% show_cols()

paletteer_d(`"rtist::oldenburg"`, n = 5) %>% show_cols()

Hier standen die Werke bekannter Male Pate, weniger unsere Desiderata.

11 ggsci

paletteer_d(`"ggsci::default_locuszoom"`, n = 5) %>% show_cols()

paletteer_d(`"ggsci::legacy_tron"`, n = 5) %>% show_cols()

Es gibt auch dynamische Paletten:

paletteer_dynamic(`"ggthemes_solarized::blue"`, n = 5) %>% show_cols()

12 jcolors

paletteer_d(`"jcolors::default"`, n = 5) %>% show_cols()

paletteer_d(`"jcolors::pal5"`, n = 5) %>% show_cols()

paletteer_d(`"jcolors::rainbow"`, n = 5) %>% show_cols()

13 Viridis

Viridis ist eine bekannte Farbpalette.

paletteer_c("viridis::viridis", n = 5)
#> <colors>
#> #440154FF #3B528BFF #21908CFF #5DC863FF #FDE725FF
paletteer_c("viridis::viridis", n = 5) %>% 
  show_cols()

paletteer_c("viridis::viridis", n = 7) %>% 
  show_cols(n = 7)

14 Magma

Eine Variante zu Viridis ist Magma:

paletteer_c("viridis::magma", n = 5)
#> <colors>
#> #000004FF #51127CFF #B63679FF #FB8861FF #FCFDBFFF
paletteer_c("viridis::magma", n = 5) %>% 
  show_cols()

15 Color Lisa

Color Lisa ist ebenfalls von bekannten Malern - bzw. deren Farbauswahl - inspiert.

paletteer_d("lisa::MarcChagall", n = 5) %>% show_cols()

paletteer_d("lisa::RobertDelaunay", n = 5) %>% show_cols()

paletteer_d("lisa::GeneDavis", n = 5) %>% show_cols()

16 Okabe-Ito

Okabe und Ito stellen eine Palette bereit, die unseren Anforderungen genügt!

paletteer_d("colorblindr::OkabeIto")
#> <colors>
#> #E69F00FF #56B4E9FF #009E73FF #F0E442FF #0072B2FF #D55E00FF #CC79A7FF #999999FF
paletteer_d("colorblindr::OkabeIto") %>% show_cols(n=8)

Sagen wir uns gefallen die folgenden 5 Farben daraus:

okebeito_auswahl <- paletteer_d("colorblindr::OkabeIto")[c(1,3,4,5,7)]
okebeito_auswahl
#> <colors>
#> #E69F00FF #009E73FF #F0E442FF #0072B2FF #CC79A7FF
okebeito_auswahl %>%  show_cols()

Es gibt ein R-Paket, ggokebito, das die Farbwahl für ggplot verfügbar macht.

library(ggokabeito)

ggplot(mpg, aes(cty, hwy, color = class)) +
  geom_point() +
  scale_color_okabe_ito()

Oder für Füllfarben:

ggplot(mpg, aes(hwy, color = class, fill = class)) +
  geom_density() +
  scale_fill_okabe_ito(name = "Class", alpha = .9) +
  scale_color_okabe_ito(name = "Class")

Die Farbnamen findet man z.B. hier.

17 Tableau 10

show_col(tableau_color_pal("Tableau 10")(10))

18 Farbnamen

library(plotrix)

paletteer_d("colorblindr::OkabeIto") %>% 
  map(color.id)
#> [[1]]
#> [1] "orange2"
#> 
#> [[2]]
#> [1] "steelblue2"
#> 
#> [[3]]
#> [1] "cyan4"    "darkcyan"
#> 
#> [[4]]
#> [1] "goldenrod1"
#> 
#> [[5]]
#> [1] "dodgerblue3"
#> 
#> [[6]]
#> [1] "darkorange3"
#> 
#> [[7]]
#> [1] "pink3"
#> 
#> [[8]]
#> [1] "gray60" "grey60"

19 Show color 2

Natürlich hat jemand die Funktion show_cols schon geschrieben, z.B. im Paket scales:

scales::show_col(paletteer_d("colorblindr::OkabeIto"))

20 Farbenblindheit

20.1 Okabe Ito

show_cols(paletteer_d("colorblindr::OkabeIto"), n = 8) %>% 
  cvd_grid()

Insgesamt stimmen die Resultate nicht so ganz zufrieden.

Versuchen wir es mit 5 Farben aus Okabe und Ito:

show_cols(paletteer_d("colorblindr::OkabeIto")) %>% 
  cvd_grid()

Besser.

Oder mit nur 3 Farben?

show_cols(paletteer_d("colorblindr::OkabeIto"), n = 3) %>% 
  cvd_grid()

Noch etwas besser.

20.2 Gene Davis

paletteer_d("lisa::GeneDavis") %>% 
  show_cols() %>% 
  cvd_grid()

Naja, einigermaßen ok.

20.3 X18

paletteer_d(`"beyonce::X18"`) %>% 
  show_cols() %>% 
  cvd_grid()

Nicht super, aber vielleicht geht es nicht viel besser.

20.4 Tableau 10

show_cols(tableau_color_pal("Tableau 10")(10)) %>% 
  cvd_grid()

Nicht so super.

20.5 Viridis

paletteer_c("viridis::viridis", n = 7) %>% 
  show_cols(n = 7) %>% 
  cvd_grid()

Oh, gut!

Probieren wir mit 5 Farben, dann wird es sogar noch einfacher.

paletteer_c("viridis::viridis", n = 5) %>% 
  show_cols(n = 5) %>% 
  cvd_grid()

Viridis sieht bei Farbschwäche super aus. Allerdings ist Viridis nicht unbedingt geignet, um nominale Variablen darzustellen, zumindest hat man einen “natürlichen” Verlauf der Farbe, was eine Sequenz oder eine ordinale Abfolge suggiert.

21 Fazit

Mittlerweile gibt es eine Reihe guter Farbpaletten (für R). Okabe und Ito ist ein Beispiel für eine gute Wahl. Es gibt aber auch noch andere; so hat Base R mittlerweile auch eine gute Standardpalette.

22 Reproducibility

#> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.1 (2022-06-23)
#>  os       macOS Big Sur ... 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       Europe/Berlin
#>  date     2023-06-30
#>  pandoc   3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  blogdown      1.16    2022-12-13 [1] CRAN (R 4.2.0)
#>  bookdown      0.34    2023-05-09 [1] CRAN (R 4.2.0)
#>  bslib         0.5.0   2023-06-09 [1] CRAN (R 4.2.0)
#>  cachem        1.0.8   2023-05-01 [1] CRAN (R 4.2.0)
#>  cli           3.6.1   2023-03-23 [1] CRAN (R 4.2.0)
#>  codetools     0.2-19  2023-02-01 [1] CRAN (R 4.2.0)
#>  colorout    * 1.2-2   2022-06-13 [1] local
#>  colorspace    2.1-0   2023-01-23 [1] CRAN (R 4.2.0)
#>  crayon        1.5.2   2022-09-29 [1] CRAN (R 4.2.1)
#>  digest        0.6.32  2023-06-26 [1] CRAN (R 4.2.0)
#>  dplyr       * 1.1.2   2023-04-20 [1] CRAN (R 4.2.0)
#>  evaluate      0.21    2023-05-05 [1] CRAN (R 4.2.0)
#>  fansi         1.0.4   2023-01-22 [1] CRAN (R 4.2.0)
#>  farver        2.1.1   2022-07-06 [1] CRAN (R 4.2.0)
#>  fastmap       1.1.1   2023-02-24 [1] CRAN (R 4.2.0)
#>  forcats     * 1.0.0   2023-01-29 [1] CRAN (R 4.2.0)
#>  generics      0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
#>  ggplot2     * 3.4.2   2023-04-03 [1] CRAN (R 4.2.0)
#>  glue          1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
#>  gtable        0.3.3   2023-03-21 [1] CRAN (R 4.2.0)
#>  highr         0.10    2022-12-22 [1] CRAN (R 4.2.0)
#>  hms           1.1.3   2023-03-21 [1] CRAN (R 4.2.0)
#>  htmltools     0.5.5   2023-03-23 [1] CRAN (R 4.2.0)
#>  jquerylib     0.1.4   2021-04-26 [1] CRAN (R 4.2.0)
#>  jsonlite      1.8.5   2023-06-05 [1] CRAN (R 4.2.0)
#>  knitr         1.43    2023-05-25 [1] CRAN (R 4.2.0)
#>  labeling      0.4.2   2020-10-20 [1] CRAN (R 4.2.0)
#>  lifecycle     1.0.3   2022-10-07 [1] CRAN (R 4.2.0)
#>  lubridate   * 1.9.2   2023-02-10 [1] CRAN (R 4.2.0)
#>  magrittr      2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
#>  paletteer   * 1.5.0   2022-10-19 [1] CRAN (R 4.2.0)
#>  pillar        1.9.0   2023-03-22 [1] CRAN (R 4.2.0)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
#>  prismatic     1.1.1   2022-08-15 [1] CRAN (R 4.2.0)
#>  purrr       * 1.0.1   2023-01-10 [1] CRAN (R 4.2.0)
#>  R6            2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
#>  readr       * 2.1.4   2023-02-10 [1] CRAN (R 4.2.0)
#>  rematch2      2.1.2   2020-05-01 [1] CRAN (R 4.2.0)
#>  rlang         1.1.1   2023-04-28 [1] CRAN (R 4.2.0)
#>  rmarkdown     2.22    2023-06-01 [1] CRAN (R 4.2.0)
#>  rstudioapi    0.14    2022-08-22 [1] CRAN (R 4.2.0)
#>  sass          0.4.6   2023-05-03 [1] CRAN (R 4.2.0)
#>  scales        1.2.1   2022-08-20 [1] CRAN (R 4.2.0)
#>  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
#>  stringi       1.7.12  2023-01-11 [1] CRAN (R 4.2.0)
#>  stringr     * 1.5.0   2022-12-02 [1] CRAN (R 4.2.0)
#>  tibble      * 3.2.1   2023-03-20 [1] CRAN (R 4.2.0)
#>  tidyr       * 1.3.0   2023-01-24 [1] CRAN (R 4.2.0)
#>  tidyselect    1.2.0   2022-10-10 [1] CRAN (R 4.2.0)
#>  tidyverse   * 2.0.0   2023-02-22 [1] CRAN (R 4.2.0)
#>  timechange    0.2.0   2023-01-11 [1] CRAN (R 4.2.0)
#>  tzdb          0.3.0   2022-03-28 [1] CRAN (R 4.2.0)
#>  utf8          1.2.3   2023-01-31 [1] CRAN (R 4.2.0)
#>  vctrs         0.6.3   2023-06-14 [1] CRAN (R 4.2.0)
#>  wesanderson * 0.3.6   2018-04-20 [1] CRAN (R 4.2.0)
#>  withr         2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
#>  xfun          0.39    2023-04-20 [1] CRAN (R 4.2.0)
#>  yaml          2.3.7   2023-01-23 [1] CRAN (R 4.2.0)
#> 
#>  [1] /Users/sebastiansaueruser/Rlibs
#>  [2] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────