Styling {ggplot2} graphics for accessibility

Nicola Rennie

My R Journey (so far…)

My R Journey (so far…)

A stream graph showing the use of R for the author between 2014 and present day. The y-axis represents the general quantity of how often R was used, with no units. An increase is seen from 2019, and then more significantly in the last year.

My {ggplot2} journey (so far…)

A radar chart showing personality traits of Villanelle from Killing Eve. Traits shown include sarcastic, assertive, competent, hedonist, mysterious, narcissistic, and rebellious. The character scores highly in all. A photograph of the character is shown in the middle of the radar chart. The Killing Eve logo is shown at the top. The graphic is sized to fit best on mobile view. A radar chart showing personality traits of Eve from Killing Eve. Traits shown include sarcastic, assertive, competent, hedonist, mysterious, narcissistic, and rebellious. The character scores just above 50% in all. A photograph of the character is shown in the middle of the radar chart. The Killing Eve logo is shown at the top. The graphic is sized to fit best on mobile view. A radar chart showing personality traits of Carolyn from Killing Eve. Traits shown include sarcastic, assertive, competent, hedonist, mysterious, narcissistic, and rebellious. The character scores between 60 - 83% for all. A photograph of the character is shown in the middle of the radar chart. The Killing Eve logo is shown at the top. The graphic is sized to fit best on mobile view.

My {ggplot2} journey (so far…)

A bar chart showing the number of books by the top 10 authors on the New York bestsellers list, where the bars are constructed of book titles stacked on top of each other. The background is black and the titles of the books are coloured white. The ten authors shown are, in order, Danielle Steele, Stuarrt Woods, Stephen King, Robert B. Parker, John Sandford, David Baldacci, Dean Koontz, Mary Higgins Clark, Sandra Brown, and Nora Roberts. Danielle Steele is the most popular author by far with 116 books on the list.

My {ggplot2} journey (so far…)

A chart showing nine different starbucks drinks (on the y axis) and different sizes of cups (on the x axis). For each combination of drink and size on offer, an icon of a cup is drawn. The size of the icon relates to the size of the cup. The shade of green of the icon relates to the amount of caffeine in the drink, with darker green denoted higher caffeine content. The Starbucks logo is shown at the top of the graphic.

My {ggplot2} journey (so far…)

A flowchart titled The Goldilocks Decision Tree. The flowchart shows the decisions made in the story of goldilocks and the three bears. The decisions included are: porridge (too hot, just right, too cold), chairs (too big, just right, too small), beds (too hard, just right, too soft). The flowchart ends with bears. A drawing of the bears and goldilocks has been added to the top-right corner, obtained from the New York Public Library.

What do I do at Jumping Rivers?

Consultancy Hex stickers for four R packages - dplyr, ggplot2, tibble, and readr.

Training Cartoon of a teacher at the front of a class with a board showing an R.

R Community Shiny in Production conference logo of a robot holding a spanner with its left hand. The hex sticker for the Shiny R package is shown on front of the robot.

Resources

Styling {ggplot2} graphics for accessibility


  Fonts


  Colours


  Alt Text

  Fonts

Fonts in {ggplot2}

  • {extrafont}
  • {ragg}
  • {showtext}

Fonts in {ggplot2}


Choose a font: fonts.google.com


Screenshot of Bungee Shade font on Google Fonts with the sample text reading Whereas recognition of the inherent dignity.

Fonts in {ggplot2}


Choose a font: fonts.google.com


Load it into R:

library(showtext)
font_add_google(name = "Bungee Shade", 
                family = "bungee")
showtext_auto()

Fonts in {ggplot2}

Let’s make an example plot to demonstrate…

name n
Crowned lemur 2094
Ring-tailed lemur 7490
Gray mouse lemur 12275

A group of eight ring-tailed lemurs huddled together on a wooden structure and looking at the camera. Image: Unsplash

Fonts in {ggplot2}

ggplot(lemurs, 
       aes(x = name,
           y = n)) +
  geom_col() +
  labs(title = "Lemurs!")

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The plot is titled Lemurs! and the plot title is shown with the default font.

Fonts in {ggplot2}

ggplot(lemurs, 
       aes(x = name,
           y = n)) +
  geom_col() +
  labs(title = "Lemurs!") +
  theme(
    plot.title = element_text(
      family = "bungee"))

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The plot is titled Lemurs! and the plot title is shown with the newly imported Bungee Shade font.

How do I choose a font?

Screenshot of Google Fonts search page with top three font samples shown.

How do I choose a font?

Sans serif


Serif


Monospace

How do I choose a font?

Sans serif: Does it pass the 1Il test?


Serif: Does it pass the 1Il test?


Monospace: Does it pass the 1Il test?

Font recommendations

  • Calibri

  • Source Sans Pro

  • Noto Sans

  • Raleway

  Colours

Colour elements in {ggplot2}

Colour of geoms (mapped to variables in aes())

A bar chart bar chart showing A, B, and C on the x axis with values 1, 2, and 3 on the y axis. Bars are coloured based on the x axis values.

Colour of geoms (not mapped in aes())

A bar chart bar chart showing A, B, and C on the x axis with values 1, 2, and 3 on the y axis. Bars are all coloured blue.

theme() elements e.g. background colour

A bar chart bar chart showing A, B, and C on the x axis with values 1, 2, and 3 on the y axis. The background of the plot is coloured blue.

Defining colours in {ggplot2}

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col()

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species using the default colour scheme.

Choosing colours in {ggplot2}

scale_*_brewer(): colorbrewer2.org

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_brewer(
    palette = "Dark2")

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species using the Dark2 colorbrewer colour scheme.

Choosing colours in {ggplot2}

Colour palette packages: github.com/EmilHvitfeldt/paletteer

library(rcartocolor)
ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_carto_d("Prism")

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species using the Prism palette from rcartocolor.

Choosing colours in {ggplot2}

Defining your own colours

Choosing colours in {ggplot2}

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#157145",
               "#4C1E4F",
               "#DE6E4B"))

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species using the manual choice of colours.

Are your colours accessible?

  • Check if the palette package has a colorblindfriendly argument

    • e.g. display_carto_all(colorblind_friendly = TRUE) from {rcartocolor}.
  • Perform your own checks…

{colorblindcheck}

my_colours = c("#157145", "#4C1E4F", "#DE6E4B")
colorblindcheck::palette_check(my_colours)
          name n tolerance ncp ndcp  min_dist mean_dist max_dist
1       normal 3  44.33725   3    3 44.337246  48.67622 55.30187
2 deuteranopia 3  44.33725   3    1 25.872723  34.57704 50.79886
3   protanopia 3  44.33725   3    1  9.345734  31.53395 46.54013
4   tritanopia 3  44.33725   3    2 41.560179  50.49023 60.86996

{colorblindr}

g <- ggplot(lemurs, 
            aes(x = name,
                y = n,
                fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#157145",
               "#4C1E4F",
               "#DE6E4B"))

Check it with {colorblindr}:

library(colorblindr)
cvd_grid(g)

{colorblindr}

A 2x2 grid of 4 bar charts. Each bar chart is titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species using a manual choice of colours. Each bar chart in the grid shows how the colours appear under different forms of colourblindness. The graph on the top right shows that not all of the colours are distinguishable.

Background colours

theme(plot.background = element_rect(fill = "transparent",
                                     colour = "transparent"),
      panel.background = element_rect(fill = "transparent",
                                      colour = "transparent"))

Don’t just use colours

ggplot(mtcars,
       aes(x = mpg,
           y = disp,
           colour = factor(cyl),
           shape = factor(cyl))) +
  geom_point(size = 4)

A scatter plot showing of the mtcars data set from ggplot2. On the x axis is the mpg variable, and on the y axis is the disp variable. Points are coloured and shaped by the cyl variable which takes values 4, 6, or 8. The plot does not have a title or legend. The plot demonstrates the combined use of colour and shape for better accessibility.

Don’t just use colours

library(ggpattern)
ggplot(lemurs, 
       aes(x = name,
           y = n, 
           fill = name,
           pattern = name)) +
  geom_col_pattern()

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. Bars are coloured by species, and bars are also filled with different patterns to highlight combined use of colour and pattern for accessibility.

  Alt Text

What is alt text?


Text providing a description of what an image contains for people who use screen readers.

How to write alt text for plots

Screenshot of article explaining how to write alt text for graphs, stating it should contain the chart type, type of data, what the chart shows, and a link to the dataset. Link: medium.com/nightingale/writing-alt-text-for-data-visualization-2a218ef43f81

An example of poor alt text

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown.

A plot of number of lemurs per species.

An example of better alt text

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown.

Writing alt text in {ggplot2}

g <- ggplot(lemurs, aes(x = name, y = n, fill = name)) +
  geom_col() +
  labs(x = "",
       y = "Number of lemurs",
       title = "Lemurs at Duke Lemur Center", 
       alt = "A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown.") 

Extract the alt text:

get_alt_text(g)
[1] "A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown."

Alt text in R Markdown


{r, fig.alt="A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown."}


{r, fig.alt=ggplot2::get_alt_text(g)}

Alt text in Quarto

```{r}
#| eval: false
#| fig.alt: "A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown."
#| fig-align: center
g
```
```{r}
#| fig.alt: !expr ggplot2::get_alt_text(g)
#| fig-align: center
#| output-location: slide
g
```

Alt text in Quarto

A bar chart titled Lemurs at Duke Lemur Center. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown.

Alt text in Shiny

renderPlot({
        <code to generate plot goes here>
      },
      alt = reactive({
        <code to generate alt text dynamically goes here>
      })
)

Automatically generating alt text


Never as good as alt text written by a human

Often misses the “what’s the point?” element of the plot

Potentially useful in interactive graphics if carefully considered

Automatically generating alt text

library(BrailleR)
VI(g)
This chart has title 'Lemurs at Duke Lemur Center'.
It has x-axis '' with labels Crowned
lemur, Gray mouse
lemur and Ring-tailed
lemur.
It has y-axis 'Number of lemurs' with labels 0, 2500, 5000, 7500, 10000 and 12500.
There is a legend indicating fill is used to show name, with 3 levels:
Crowned
lemur shown as strong reddish orange fill, 
Gray mouse
lemur shown as vivid yellowish green fill and 
Ring-tailed
lemur shown as brilliant blue fill.
The chart is a bar chart with 3 vertical bars.
Bar 1 is centered horizontally at Crowned
lemur, and spans vertically from 0 to 2094 with fill colour strong reddish orange which maps to name = Crowned
lemur.
Bar 2 is centered horizontally at Ring-tailed
lemur, and spans vertically from 0 to 7490 with fill colour brilliant blue which maps to name = Ring-tailed
lemur.
Bar 3 is centered horizontally at Gray mouse
lemur, and spans vertically from 0 to 12275 with fill colour vivid yellowish green which maps to name = Gray mouse
lemur.
These are stacked, as sorted by name.

Automatically generating alt text

```{r}
#| results: hide
#| fig-alt: !expr paste(VI(g)$text, sep = " ", collapse = " ")
g
```
This chart has title 'Lemurs at Duke Lemur Center'. It has x-axis '' with labels Crowned lemur, Gray mouse lemur and Ring-tailed lemur. It has y-axis 'Number of lemurs' with labels 0, 2500, 5000, 7500, 10000 and 12500. There is a legend indicating fill is used to show name, with 3 levels: Crowned lemur shown as strong reddish orange fill,  Gray mouse lemur shown as vivid yellowish green fill and  Ring-tailed lemur shown as brilliant blue fill. The chart is a bar chart with 3 vertical bars. Bar 1 is centered horizontally at Crowned lemur, and spans vertically from 0 to 2094 with fill colour strong reddish orange which maps to name = Crowned lemur. Bar 2 is centered horizontally at Ring-tailed lemur, and spans vertically from 0 to 7490 with fill colour brilliant blue which maps to name = Ring-tailed lemur. Bar 3 is centered horizontally at Gray mouse lemur, and spans vertically from 0 to 12275 with fill colour vivid yellowish green which maps to name = Gray mouse lemur. These are stacked, as sorted by name.

Resources

{ggplot2}

Accessibility

Questions?