---
title: "Paul Tol's Color Schemes"
author: "N. Frerebeau"
date: "`r Sys.Date()`"
output:
  markdown::html_format:
    options:
      toc: true
      number_sections: true
vignette: >
  %\VignetteIndexEntry{Paul Tol's Color Schemes}
  %\VignetteEngine{knitr::knitr}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  out.width = "100%"
)
```

```{r packages}
library(khroma)
```

## Introduction

Tol (2021) offers carefully chosen schemes, ready for each type of data, with colors that are:

* Distinct for all people, including color-blind readers,
* Distinct from black and white,
* Distinct on screen and paper,
* Matching well together.

All the scales presented in Paul Tol's technical note (issue 3.2, 2021-08-18) are implemented here, for use with base R **graphics**, [**ggplot2**](https://cran.r-project.org/package=ggplot2) and [**ggraph**](https://cran.r-project.org/package=ggraph).

## Qualitative data

According to Paul Tol's technical note, the *bright*, *contrast*, *vibrant* and *muted* color schemes are color-blind safe.

The *light* color scheme is reasonably distinct for both normal or color-blind vision and is intended to fill labelled cells.

The *pale* and *dark* schemes are not very distinct in either normal or color-blind vision and should be used as a text background or to highlight a cell in a table.

The qualitative color schemes must be used as given (no interpolation): colors are picked up to the maximum number of supported values. Refer to the original document for details about the recommended uses (see references).

| Scheme            | Max. colors  |
|:------------------|-------------:|
| `bright`          | 7            |
| `high contrast`   | 3            |
| `vibrant`         | 7            |
| `muted`           | 9            |
| `medium contrast` | 3            |
| `pale`            | 6            |
| `dark`            | 6            |
| `light`           | 9            |

### *bright*
```{r tol_quali_bright, fig.height = 2, fig.width = 7}
bright <- color("bright")
plot_scheme(bright(7), colours = TRUE, names = TRUE, size = 0.9)
```

### *high contrast*
```{r tol_quali_highcontrast, fig.height = 2, fig.width = 7}
highcontrast <- color("high contrast")
plot_scheme(highcontrast(3), colours = TRUE, names = TRUE, size = 0.9)
```

### *vibrant*
```{r tol_quali_vibrant, fig.height=2, fig.width=7}
vibrant <- color("vibrant")
plot_scheme(vibrant(7), colours = TRUE, names = TRUE, size = 0.9)
```

### *muted*
```{r tol_quali_muted, fig.height=2, fig.width=7}
muted <- color("muted")
plot_scheme(muted(9), colours = TRUE, names = TRUE, size = 0.9)
```

### *medium contrast*
```{r tol_quali_mediumcontrast, fig.height = 2, fig.width = 7}
mediumcontrast <- color("medium contrast")
plot_scheme(mediumcontrast(6), colours = TRUE, names = TRUE, size = 0.9)
```

### *pale* and *dark*
```{r tol_quali_pale_dark, fig.height=2, fig.width=7}
pale <- color("pale")
plot_scheme(pale(6), colours = TRUE, names = TRUE, size = 0.9)

dark <- color("dark")
plot_scheme(dark(6), colours = TRUE, names = TRUE, size = 0.9)
```

### *light*
```{r tol_quali_light, fig.height=2, fig.width=7}
light <- color("light")
plot_scheme(light(9), colours = TRUE, names = TRUE, size = 0.9)
```

## Diverging data

If more colors than defined are needed from a given scheme, the color coordinates are linearly interpolated to provide a continuous version of the scheme.

| Scheme      | Num. of colors  | Bad data |
|:------------|----------------:|---------:|
| `sunset`    | 11              | #FFFFFF  |
| `nightfall` | 17              | #FFFFFF  |
| `BuRd`      | 9               | #FFEE99  |
| `PRGn`      | 9               | #FFEE99  |

### *sunset*
```{r tol_div_sunset, fig.height=2, fig.width=7}
sunset <- color("sunset")
plot_scheme(sunset(11), colours = TRUE, size = 0.9)
```

### *nightfall*
```{r tol_div_nightfall, fig.height=2, fig.width=7}
nightfall <- color("nightfall")
plot_scheme(nightfall(17), colours = TRUE, size = 0.9)
```

### *BuRd*
```{r tol_div_BuRd, fig.height=2, fig.width=7}
BuRd <- color("BuRd")
plot_scheme(BuRd(9), colours = TRUE, size = 0.9)
```

### *PRGn*
```{r tol_div_PRGn, fig.height=2, fig.width=7}
PRGn <- color("PRGn")
plot_scheme(PRGn(9), colours = TRUE, size = 0.9)
```

## Sequential data

If more colors than defined are needed from a given scheme, the color coordinates are linearly interpolated to provide a continuous version of the scheme, with the exception of the *discrete rainbow* scheme (see below).

| Scheme             | Num. of colors  | Bad data |
|:-------------------|----------------:|---------:|
| `YlOrBr`           | 9               | #888888  |
| `iridescent`       | 23              | #999999  |
| `incandescent`     | 11              | #888888  |
| `discrete rainbow` | 23              | #777777  |
| `smooth rainbow`   | 34              | #666666  |

### *YlOrBr*
```{r tol_seq_YlOrBr, fig.height=2, fig.width=7}
YlOrBr <- color("YlOrBr")
plot_scheme(YlOrBr(9), colours = TRUE, size = 0.9)
```

### *iridescent*
```{r tol_seq_iridescent, fig.height=2, fig.width=7}
iridescent <- color("iridescent")
plot_scheme(iridescent(23), colours = TRUE, size = 0.5)
```

### *incandescent*
```{r tol_seq_incandescent, fig.height=2, fig.width=7}
incandescent <- color("incandescent")
plot_scheme(incandescent(11), colours = TRUE, size = 0.5)
```

### *rainbow*
As a general rule, ordered data should not be represented using a rainbow scheme. There are three main arguments against such use (Tol 2021):

* The spectral order of visible light carries no inherent magnitude message.
* Some bands of almost constant hue with sharp transitions between them, can be perceived as jumps in the data.
* Color-blind people have difficulty distinguishing some colors of the rainbow.

If such use cannot be avoided, Paul Tol's technical note provides two color schemes that are reasonably clear in color-blind vision. To remain color-blind safe, these two schemes must comply with the following conditions:

*discrete rainbow*
: This scheme must not be interpolated.

*smooth rainbow*
: This scheme does not have to be used over the full range. Tol (2021) suggests starting at purple.

```{r tol_seq_rainbow, fig.height=2, fig.width=7}
discrete_rainbow <- color("discrete rainbow")
plot_scheme(discrete_rainbow(14), colours = TRUE, size = 0.7)
```

When using the *smooth rainbow* scheme:

* Start off-white instead of purple if the lowest data value occurs often;
* End at red instead of brown the highest data value occurs often.

```{r tol_seq_adjust, fig.height=2, fig.width=7}
smooth_rainbow <- color("smooth rainbow")

## Start at purple instead of off-white
plot(smooth_rainbow(256, range = c(0.25, 1)))
## End at red instead of brown
plot(smooth_rainbow(256, range = c(0, 0.9)))
```

## Diagnostic maps
### Qualitative color schemes

```{r tol_quali, echo=FALSE, fig.height = 2, fig.width = 7, fig.show='hold', fig.cap='Diagnostic maps for the bright, vibrant, muted and light (from top to bottom) qualitative color schemes.'}
set.seed(12345)
plot_map(bright(7))
plot_map(vibrant(7))
plot_map(muted(9))
plot_map(light(9))
```

### Diverging schemes

```{r tol_div, echo=FALSE, fig.height = 2, fig.width = 7, fig.show='hold', fig.cap='Diagnostic maps for the sunset, BuRd and PRGn (from top to bottom) diverging color schemes.'}
set.seed(12345)
plot_map(sunset(11))
plot_map(nightfall(17))
plot_map(BuRd(9))
plot_map(PRGn(9))
```

```{r tol_div_map, echo=FALSE, fig.height = 7, fig.width = 7, out.width='50%', fig.show='hold', fig.cap='Diagnostic maps for the sunset, BuRd and PRGn diverging color schemes.'}
plot_tiles(color("sunset")(128), n = 256)
plot_tiles(color("nightfall")(128), n = 256)
plot_tiles(color("BuRd")(128), n = 256)
plot_tiles(color("PRGn")(128), n = 256)
```

### Sequential schemes

```{r tol_seq, echo=FALSE, fig.height = 2, fig.width = 7, fig.show='hold', fig.cap='Diagnostic maps for the YlOrBr, iridescent, discrete rainbow and smooth rainbow (from top to bottom) sequential color schemes.'}
set.seed(12345)
plot_map(YlOrBr(9))
plot_map(iridescent(23))
plot_map(incandescent(11))
plot_map(discrete_rainbow(14))
plot_map(smooth_rainbow(23))
```

```{r tol_seq_map, echo=FALSE, fig.height = 7, fig.width = 7, out.width='50%', fig.show='hold', fig.cap='Diagnostic maps for the YlOrBr, iridescent and smooth rainbow sequential color schemes.'}
plot_tiles(color("YlOrBr")(128), n = 256)
plot_tiles(color("iridescent")(128), n = 256)
plot_tiles(color("incandescent")(128), n = 256)
plot_tiles(color("smooth rainbow")(128), n = 256)
```

## References

Tol, P. 2021. "Colour Schemes." Technical note SRON/EPS/TN/09-002 3.2. SRON. URL: <https://sronpersonalpages.nl/~pault/data/colourschemes.pdf>.
