Skip to contents

plot_lint() compiles a plot and reports the design problems a static render hides from a green test suite: text too small to read, colour contrast below the WCAG threshold, two palette colours a colour-blind reader cannot tell apart, labels that overlap or fall off the panel, and grammar-level mistakes such as an encoding with a single level or a legend too long to read. It is the "flag it" step of the accessibility workflow — pair it with render_plot(cvd = ) to see a failing palette and scale_pattern() / pattern_hatch() to fix it with a redundant non-colour encoding.

Usage

plot_lint(x, ..., min_text_px = 7, min_contrast = 3)

Arguments

x

A PlotSpec (or anything vellum::as_vellum_scene() accepts).

...

Passed to vellum::vl_lint(): rules, exclude, severity, cvd, min_text_pt, max_overplot and the rest of the thresholds.

min_text_px

Minimum legible text height in pixels (default 7); text below it is flagged.

min_contrast

Minimum acceptable contrast ratio between a mark and its background (default 3, the WCAG AA threshold for graphical objects).

Value

A data frame (class vellum_lint) with one row per finding: rule, severity ("warning"/"note"), node, a human message, and the device-px box x0/y0/x1/y1NA for a grammar finding, which is about a scale and so has no box. Zero rows when the plot is clean.

Details

The geometric rules come from the engine's vellum::vl_lint(), which judges them in resolved device pixels. The grammar rules are registered into the same registry by vellumplot, so they are not special: vellum::vl_lint_rules() lists them, rules = selects them, and vellum::vl_lint() on a compiled plot reports them too. Findings are returned most-severe first.

Because every finding carries the box it refers to, vellum::vl_lint_overlay() can draw the report onto the plot, and vellum::vl_lint_assert() can fail a test on it.

A composition or table has no single set of trained scales, so it reports the geometric findings only — lint the cells individually for the grammar ones (vellumplot#147).

Examples

# a tiny-text, single-level-scale plot trips the linter
p <- vplot(transform(mtcars, grp = "one group")) |>
  mark_point(x = wt, y = mpg, color = grp) |>
  theme(axis.text = element_text(size = 2))
plot_lint(p)
#> 9 lint findings (8 warnings):
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [single_level_scale] scale:color: The color scale has a single level (one
#>   group): the encoding conveys nothing and its legend is redundant.

# the engine's arguments come through, so a project can accept a finding
plot_lint(p, exclude = "scale:color")
#> 8 lint findings (8 warnings):
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor
#>  [tiny_text] text: 2.7 px tall - below the 7 px legibility floor