Simulating color-vision deficiency

Author

Ian Lyttle

Published

2022-05-17

One of the great things about the colorspace package is that it provides a model to simulate color-vision deficiency, by Machado et al. (2009). This model has been adpated to Observable.

Using Quarto for HMTL, you can import this Observable widget to simulate color-vision deficiency for your entire page. Just open the “twistie”, and away you go:

Color-vision deficiency

Check out the performance of the viridis palette:

library("scales")
show_col(viridis_pal()(16), labels = FALSE)

…as compared with a hue-based palette:

show_col(hue_pal()(16), labels = FALSE)

How to use

You’ll need a recent version of Quarto; just copy-paste this snippet into your .qmd file, wherever you want the input to appear:

<details>
<summary>Color-vision deficiency</summary>
```{ojs}
//| echo: false
import {inputCvd, filterCvd} from "@ijlyttle/cvd-widget@618"

viewof cvd = inputCvd({label: ""});

filterCvd(cvd, {selector: "html"});
```
</details>

There are four components to this code:

  • The enclosing HTML provides the wee “twistie” to reveal and hide the input.

  • You import a couple of functions from an Observable notebook. I provide a fixed version; if you want to use the latest version, you can remove the @618.

  • The function inputCvd() creates an Observable input-form. It has a single argument, an object with three optional elements:

    • label: String, with default: "Color-vision deficiency".
    • condition: String ["none", "protan", "deuteran", "tritan"], with default: "deuteran".
    • severity: Number \(0 \leq t \leq 1\), with default: 0.

    It returns an object with two elements: condition and severity.

  • The function filterCvd() takes two arguments:

    • input: an object with two elements: condition and severity.
    • an object with a single optional element:
      • selector: String, CSS selector for the filter, with default: ".observablehq-root".

    It has the side-effect of applying an SVG filter to all the HTML elements specified by selector.

For use in Quarto, I set the label to an empty string because I’m using the “twistie”. Also, I set the selector to "html" because Quarto gives access to the top-level <html> element (Observable notebooks provide iframes, instead).

For more details on how it works, please check out the Observable notebook.