Alt Text in R: Plots, Reports, and Shiny
What is alt text?
Alt text (short for alternative text) is text that describes the appearance and purpose of an image. Alt text has multiple purposes, the main one being that it aids visually impaired users to better understand your content when the alt text is read aloud by screen readers. Alt text is also used in place of an image if it fails to load, which means that users with poor internet connection are more likely to be able to engage with your content.
How do I write alt text?
There are already a lot of good resources on how to write alt text, and so that’s not the main focus of this blog post. This Medium article by Amy Cesal describes a simple formula for helping you to write alt text for charts, which I’ve found really helpful. Liz Hare also recently gave a talk on alt text for R-Ladies New York, and the slides are an excellent resource.
Can I automate writing alt text?
One of the often-cited arguments for using programming languages, such as R, is that they allow you to automate processes. And so you may very well be wondering “can I use R to automate the writing of alt text?” Before I answer that question, let me remind you of the phrase just because you can, doesn’t mean you should.
The examples of automated alt text to describe plots that I’ve seen tend to describe which variables are on the x and y axes, the range of the data, the chart title, and maybe the colours in the plot. Some make attempts to describe a trend line. What’s almost always missing is the “why”. It’s very difficult to automate a description of what you’re trying to communicate to the person interpreting a plot with only a list of plot components.
One R package that may be useful as a starting point for writing alt text is the {BrailleR} package. It has support for generating alt text for both base R and {ggplot2} graphics, using the VI()
function. Since it’s still missing the “what am I supposed to be seeing” message, and it doesn’t always get it right, I’d encourage you never to rely 100% on automated alt text. It could provide a starting point for you to check, edit, and include the take-home message of your graphics.
After you’ve written the alt text for your image, you need to actually add it to your document or app. If you’re directly writing HTML code, it’s usually quite straightforward - and this guide for improving accessibility with alt text gives a great overview. Today, this blog post will show you how to include alt text in your web applications and documents when you’ve built them in R.
How do I add alt text in R?
With R, you can create static plots, documents, presentations, web applications, and many other output types - and they all need alt text! We’ll go through how you do that for the most common output types in R.
{ggplot2}
It goes without saying that {ggplot2} is one of the most popular packages for creating plots in R. So it’s likely that you’ll be adding alt text to a plot created with {ggplot2}. Within the labs()
function in {ggplot2}, there’s an argument alt
(introduced in version 3.3.4) - and this is where you can add alt text.
g <- ggplot(lemurs, aes(x = name, y = n)) +
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.")
If you save the plot as a variable, you can extract the alt text with:
get_alt_text(g)
There are a couple of reasons for using the alt
argument in {ggplot2}:
- It’s usually easier to write the alt text when you’re making the plot, rather than when you’re compiling the outputs since it’s fresher in your mind.
- The string passed to
alt
automatically gets passed as the image’s alt text if you use the plot in a Shiny app (more on that later…)
Quarto and R Markdown
Both R Markdown and Quarto (next generation R Markdown) allow you to create outputs in HTML format, such as documents or presentations. Although MS Word, and Adobe are starting to allow you to add alt text to word documents and PDFs, neither R Markdown or Quarto have support for this yet (although hopefully they will in the future). HTML outputs are more accessible in general, so I’d recommend HTML outputs where possible anyway.
If you’re creating a plot within a code chunk, you can use the fig.alt
option in R Markdown to pass in a character string of alt text:
```{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."}
g
```
and in Quarto, the idea is similar but the syntax is slightly different:
```{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."
g
```
Adding alt text directly into the code chunk options has always felt slightly clunky, and so what you can do instead is store your alt text in a variable and reference it in the code block option. Alternatively, you can make good use of the get_alt_text()
function in {ggplot2} in your R Markdown chunk options:
```{r, fig.alt=ggplot2::get_alt_text(g)}
g
```
In Quarto, you need to be a bit more explicit about the fact you’re calling a function, but it’s still pretty straightforward:
```{r}
#| fig-alt: !expr ggplot2::get_alt_text(g)
g
```
If you inspect the HTML of your R Markdown / Quarto output (by right-clicking and selecting Inspect, or using the Ctrl+Shift+I keyboard shortcut), you can see the alt text has been added to the image:
If you’re creating an output format that doesn’t allow you to add alt text, such as PDF, you should still add a description of the image somewhere. You could pass in ggplot2::get_alt_text(g)
to the fig.cap
chunk option as an alternative.
If you’re adding an image outside of a code chunk, you can add alt text to images in Quarto using:
![](lemur.png){fig-alt="A drawing of a lemur."}
and replacing fig-alt
with alt
works for R Markdown.
Shiny
Finally, on to adding alt text in Shiny apps! Since Shiny makes it easy to build web applications straight from R, it’s important that you know how to add alt text to Shiny apps from R. If you haven’t made your plots with {ggplot2}, haven’t added your alt text to the alt
argument in labs()
, or need your alt text to update, read on!
Most plots in Shiny apps are generated within a renderPlot()
call, with the first argument being the code that generates the plot. renderPlot()
also has an alt
argument (added in version 1.5.1) where you can pass in a character string of alt text for your plot:
renderPlot({
# code to generate plot goes here
},
alt = "alt text goes here"
)
However, most plots in Shiny apps have some sort of reactivity associated with them - when a user changes an input value, the plot updates. This means that the alt text should update as well. Luckily, you can pass in a reactive()
to the alt
argument in renderPlot()
:
renderPlot({
# code to generate plot goes here
},
alt = reactive({
# code to add alt text goes here
})
)
This means you can pass in different strings of alt text depending on which input values a user has selected. Depending on what the plot contains and what the user inputs do, you could construct the alt text based on the inputs. Even better, create a look-up table that returns human-written alt text based on a combination of input variables.
If you want to read more about accessibility in Shiny then check out our previous blog post on the topic.
I hope this blog post has convinced you that writing alt text is worthwhile, and not too tricky to add into your R developed documents and apps!