Skip to contents
library(a11yviz)
library(ggplot2)

dt_show <- function(df) DT::datatable(df,
  extensions = "Buttons",
  options    = list(dom        = "Bfrtip",
                    buttons    = c("copy", "csv", "excel", "pdf"),
                    pageLength = 10,
                    scrollX    = TRUE,
                    autoWidth  = TRUE),
  class      = "compact stripe hover",
  rownames   = FALSE,
  width      = "100%")

Example

p <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
  geom_point() +
  theme_grey(base_size = 8) +
  labs(x = NULL, y = NULL)
p

Audit reveals the gaps

a11y_audit() returns one row per WCAG criterion with a status column. The table below filters to actionable rows (status = "todo" or "ok") — the items where the chart needs human attention.

status meaning
ok check passes automatically
todo needs user action
applied handled by theme_a11y() / scale_color_a11y() / a11y_layout()
manual requires human review (e.g., reflow at 320 px)
css covered by a11y_css() stylesheet
doc document-level check; run a11y_check_headings() separately
dt_show(subset(a11y_audit(p), status %in% c("todo", "ok")))

Two actionable items come back as todo:

  • WCAG 2.1: alt text missing
  • WCAG 2.1: redundant group encoding (color only)

Improved

p_a11y <- ggplot(iris, aes(Sepal.Length, Sepal.Width,
                           color = Species, shape = Species)) +
  geom_point(size = 2.5) +
  scale_color_a11y("dark2_8") +
  theme_a11y("AA") +
  labs(x = "Sepal length (cm)", y = "Sepal width (cm)")
p_a11y <- a11y_alt_text(p_a11y,
  "Scatter of iris sepal width vs length by species; setosa forms a distinct cluster at short, wide sepals.")
p_a11y

Five accessibility wins from a few lines: shape = Species encodes group via marker (Success Criterion 1.4.1), scale_color_a11y("dark2_8") swaps in colors that clear 3:1 on white (Success Criterion 1.4.11; ggplot’s default scale fails here for some pairs), theme_a11y("AA") drops the grey panel background and sets AA-compliant fonts (Success Criterion 1.4.3), labs() names the axes (Success Criterion 2.4.6), and a11y_alt_text() attaches the screen-reader description (Success Criterion 1.1.1).

Audit again

dt_show(subset(a11y_audit(p_a11y), status %in% c("todo", "ok")))

All actionable checks come back as ok.

WCAG rubric

a11y_rubric() is the per-criterion reference: name, level, threshold, and the a11yviz function that addresses each. Same criterion column as a11y_audit(), so the two join cleanly.

dt_show(a11y_rubric())

Accessible CSS

a11y_css() returns the path to a stylesheet that handles dark-mode tooltips, keyboard focus rings, table styling, and responsive layout.

basename(a11y_css())
#> [1] "a11yviz.css"

More features

See the function reference for the full API.

References

  • Crameri, F., Shephard, G. E., & Heron, P. J. (2020). The misuse of colour in science communication. Nature Communications, 11, 5444.
  • Nuñez, J. R., Anderton, C. R., & Renslow, R. S. (2018). Optimizing colormaps with consideration for color vision deficiency to enable accurate interpretation of scientific data. PLoS ONE, 13(7), e0199239.
  • WCAG 2.1 specification — pass any criterion value to a11y_wcag_url() for the deep link.
  • ADA web guidance