library(colorspace)swatchplot("Hue (type of color)"=hex(polarLUV(H =seq(0, 300, length.out =10), C =50, L =70)),"Chroma (colorfulness)"=hex(polarLUV(H =0, C =seq(0, 100, length.out =10), L =65)),"Luminance (brightness)"=hex(polarLUV(H =260, C =25, L =seq(90, 10, length.out =10))))
Captures human perceptual axes well
Perceptually uniform – a unit step anywhere in HCL space produces a constant perceptual change in color
colorspace package lets you create and explore palettes based on trajectories in HCL space.
Hue
Type of color (red, blue, green, etc.)
Not perceived as ordered
Values go from 0 to 360 (color wheel)
Code
library(colorspace)hue <-polarLUV(H =seq(0, 300, 75), C =60, L =65)hue
L C H
[1,] 65 60 0
[2,] 65 60 75
[3,] 65 60 150
[4,] 65 60 225
[5,] 65 60 300
---title: "Color scales in R"author: Andrew Siefertformat: html: embed-resources: true toc: true code-fold: true code-tools: true fig-height: 4 fig-width: 6execute: warning: false---# A little color theoryThree components of color (HCL space):```{r}library(colorspace)swatchplot("Hue (type of color)"=hex(polarLUV(H =seq(0, 300, length.out =10), C =50, L =70)),"Chroma (colorfulness)"=hex(polarLUV(H =0, C =seq(0, 100, length.out =10), L =65)),"Luminance (brightness)"=hex(polarLUV(H =260, C =25, L =seq(90, 10, length.out =10))))```* Captures human perceptual axes well* Perceptually uniform -- a unit step anywhere in HCL space produces a constant perceptual change in color**colorspace** package lets you create and explore palettes based on trajectories in HCL space.## Hue* Type of color (red, blue, green, etc.)* Not perceived as ordered* Values go from 0 to 360 (color wheel)```{r}library(colorspace)hue <-polarLUV(H =seq(0, 300, 75), C =60, L =65)huehex(hue)swatchplot(hex(hue))text(x =seq(0.1, 1, 0.2), y =0.05, labels =seq(0, 300, 75))```## Chroma* Purity or colorfulness of the color* Perceived as ordered* Ranges from 0 (gray) to maximum that varies with hue and luminescence```{r}chroma <-polarLUV(H =0, C =seq(0, 100, 25), L =65) swatchplot(hex(chroma))text(x =seq(0.1, 1, 0.2), y =0.05, labels =seq(0, 100, 25))```## Luminance* Brightness* Perceived as ordered* Ranges from 0 (black) to 100 (white)```{r}lum <-polarLUV(H =260, C =25, L =seq(90, 10, -20))swatchplot(hex(lum))text(x =seq(0.1, 1, 0.2), y =0.05, labels =seq(90, 10, -20))```# Type of palettes* **Qualitative**: categorical information* **Sequential**: ordered/numerical information (high to low)* **Diverging**: ordered/numeric information around a central neutral value### Qualitative palettes* Distinguishes categories by a sequence of hues while keeping chroma and luminance constant* Best to use equidistant sequence of hues spanning the color wheel* Use lighter colors (moderate chroma, high luminance) for shading areas (e.g., bar plots, maps)* Use more flashy colors (high chroma) for points and linesQualitative palettes in **colorspace**:```{r}hcl_palettes(type ="qualitative", plot = T)```Create a palette using `qualitative_hcl()`: ```{r}my_qual <-qualitative_hcl(6, palette ="Set3")my_qualdemoplot(my_qual)# plot palette in HCL spacehclplot(my_qual)```## Sequential palettes* Codes numeric values by sequence of increasing or decreasing luminance* Without chroma (`c = 0`), corresponds to grayscale* Use larger range of luminance if you are plotting more values* Can also vary chroma and/or hue to better distinguish colors```{r}hcl_palettes("sequential (single-hue)", n =7, plot =TRUE, nrow =6)hcl_palettes("sequential (multi-hue)", n =7, plot =TRUE)``````{r}seq9 <-sequential_hcl(10, palette ="Greens 3")demoplot(seq9, "heatmap")hclplot(seq9)specplot(seq9, type ="o")```## Diverging palettes * Combination of two sequential palettes with different hues in the left and right "arms"* Neutral central value has zero chroma* Chroma and luminance trajectories are mirrored in the two arms```{r}hcl_palettes("diverging", n =7, plot =TRUE, nrow =10)``````{r}div12 <-diverging_hcl(12, palette ="Blue-Red")demoplot(div12)hclplot(div12)specplot(div12, type ="o")```# Using colorspace with ggplot2Scales are named via the scheme: `scale_<aesthetic>_<datatype>_<colorscale>(palette = <Palette>)`* `<aesthetic>` is the name of the aesthetic (`fill`, `color`, etc.)* `<datatype>` is the type of variable plotted (`discrete` or `continuous`)* `<colorscale>` sets the type of color scale used (`qualitative`, `sequential`, or `diverging`)* `<Palette>` is the name of the palette (e.g., `"Dark 3", "Blue-Red"`)```{r}library(ggplot2)ggplot(iris, aes(x = Sepal.Length, fill = Species)) +geom_density(alpha =0.6) +scale_fill_discrete_qualitative(palette ="Dark 3")```# Color blindness**colorblindr** package simulates how a color palette will look to people with common forms of color blindness. Make a figure using default ggplot color scale:```{r}df <-data.frame(x =c("a", "b", "c", "d"), y =c(3, 4, 1, 2))bars <-ggplot(df, aes(x, y, fill = x)) +geom_bar(stat ="identity") +labs(x =NULL, y =NULL) +theme(legend.position ="none")bars```Look at color-vision-deficiency simulations: ```{r}library(colorblindr)cvd_grid(bars)```A discrete color scale that works better for people with color blindness is the Okabe Ito palette. ```{r}palette_OkabeItoswatchplot(palette_OkabeIto)bars2 <- bars +scale_fill_OkabeIto()bars2cvd_grid(bars2)```# Some useful palettes## viridisviridis color scales are designed to have good perceptual properties, work well for people with colorblindness, and print well in gray scale.```{r}library(viridis)viridis(10)swatchplot("viridis"=viridis(10),"magma"=viridis(10, option ="magma"),"inferno"=viridis(10, option ="inferno"), "cividis"=viridis(10, option ="cividis"), "rocket"=viridis(10, option ="rocket"),"mako"=viridis(10, option ="mako"))```The viridis scales are available in ggplot2 using using `scale_fill_viridis_d()` and `scale_fill_viridis_c()`.Discrete viridis scale:```{r}bars +scale_fill_viridis_d()```Continuous viridis scale:```{r}erupt <-ggplot(faithfuld, aes(waiting, eruptions, fill = density)) +geom_raster()erupterupt +scale_fill_viridis_c(option ="magma")```## ColorBrewerColorBrewer scales are designed to work well for maps, but are also good for other types of data. They are available in the **RColorBrewer** package: ```{r, fig.height=10}library(RColorBrewer)display.brewer.all()```Most palettes are colorblind friendly.```{r, fig.height=8}display.brewer.all(colorblindFriendly = T)```You can construct a palette using `brewer.pal()`:```{r}brewer.pal(9, name ="PuBu")display.brewer.pal(10, name ="PuBu")```ColorBrewer scales are also built into ggplot2: * `scale_color_brewer()` and `scale_fill_brewer()` for discrete scales* `scale_color_distiller()` and `scale_fill_distiller()` for continuous scales```{r}bars +scale_fill_brewer(palette ="Set2")``````{r}erupt +scale_fill_distiller(palette ="RdPu")```## scicoscico includes 39 palettes designed for scientific data visualization. They have good perceptual properties and are colorblind safe. ```{r}library(scico)scico_palette_show()scico(20, palette ="lapaz") |>swatchplot()erupt +scale_fill_scico(palette ="davos")```# PaletteerThe **paletteer** package provides a unified interface to color scales from many packages.```{r}library(paletteer)paletteer_d("nationalparkcolors::BryceCanyon", 5)paletteer_c("scico::devon", 10)bars +scale_fill_paletteer_d("wesanderson::FantasticFox1")```# Manual scalesYou can set colors manually in ggplot2 using `scale_color_manual()` and `scale_fill_manual()`.```{r}bars +scale_fill_manual(values =c("forestgreen", "goldenrod", "firebrick", "cornflowerblue"))```Here are Erika's cheat sheets for ColorBrewer scales: ![](image1.png)![](image2.png)![](image3.png)```{r}bars +scale_fill_manual(values =c("#7FC97F", "#BEAED4", "#FDC086", "#FFFF99"))```