Summary
sntutils has 27+ built-in palettes used for choropleth maps (get_palette(), auto_bin()), but zero colorblind accessibility checks. ~8% of men have some form of color vision deficiency. We need a function that checks if a palette is safe and optionally fixes it.
Proposed function
check_palette(
palette,
n = NULL,
fix = FALSE,
severity = 1,
tolerance = 10
)
Parameters
| Param |
Type |
Default |
Description |
palette |
character |
required |
Preset name (e.g. "blues") or hex vector |
n |
integer |
NULL |
Number of colors to check (passed to get_palette()) |
fix |
logical |
FALSE |
If TRUE, return an adjusted colorblind-safe palette |
severity |
numeric |
1 |
Deficiency severity 0–1 (1 = complete) |
tolerance |
numeric |
10 |
Min perceptual distance threshold (Delta E in CIELab) |
Return value
A list with:
safe — logical, TRUE if palette passes all 3 deficiency types
colors — the input palette (hex vector)
min_dist — named numeric vector with min pairwise distance for each type + normal
details — data frame with per-type results (type, min_dist, pass)
fixed — (only when fix = TRUE) adjusted hex vector that passes the check
Core logic
Checking:
- Resolve palette via
get_palette(palette, n) to get hex vector
- For each deficiency type (deutan, protan, tritan):
a. Simulate with colorspace::deutan(), protan(), tritan()
b. Convert simulated colors to CIELab
c. Compute all pairwise Euclidean distances in Lab space
d. Record minimum distance
- If all min distances >= tolerance →
safe = TRUE
Fixing (when fix = TRUE):
- Convert input palette to HCL space
- Keep the hue endpoints (preserve color intent)
- Spread luminance values evenly from ~30 to ~90
- Rebuild palette with
colorspace::hex(colorspace::polarLUV(L, C, H))
- Re-check — if still fails, reduce chroma and widen luminance further
- If that still fails, fall back to
colorspace::sequential_hcl(n, palette = "viridis") and warn
Dependency: colorspace
Add to Imports. Provides CVD simulation, HCL conversion, and desaturation — one package handles both checking and fixing.
Files to create/modify
| File |
Action |
R/check_palette.R |
Create — new function + internal helpers |
tests/testthat/test-check_palette.R |
Create — tests |
DESCRIPTION |
Edit — add colorspace to Imports |
Example usage
# check a built-in palette
check_palette("blues", n = 6)
# check custom colors
check_palette(c("#FF0000", "#00FF00", "#0000FF"))
# check and fix
result <- check_palette("reds", n = 5, fix = TRUE)
result$safe
result$fixed
# check with partial severity
check_palette("default", n = 6, severity = 0.5)
Tests to write
- Known-safe palette (viridis) returns
safe = TRUE
- Known-bad palette (red + green only) returns
safe = FALSE
fix = TRUE returns a palette that passes the check
- Custom hex input works
- Preset name input works (resolves via
get_palette())
n parameter interpolates correctly before checking
severity = 0 always returns safe (no deficiency)
- Edge cases: single color, two colors
- Tolerance parameter affects pass/fail threshold
- Error on invalid inputs (missing palette, bad severity, bad tolerance)
Summary
sntutils has 27+ built-in palettes used for choropleth maps (
get_palette(),auto_bin()), but zero colorblind accessibility checks. ~8% of men have some form of color vision deficiency. We need a function that checks if a palette is safe and optionally fixes it.Proposed function
Parameters
palettenget_palette())fixseveritytoleranceReturn value
A list with:
safe— logical, TRUE if palette passes all 3 deficiency typescolors— the input palette (hex vector)min_dist— named numeric vector with min pairwise distance for each type + normaldetails— data frame with per-type results (type, min_dist, pass)fixed— (only whenfix = TRUE) adjusted hex vector that passes the checkCore logic
Checking:
get_palette(palette, n)to get hex vectora. Simulate with
colorspace::deutan(),protan(),tritan()b. Convert simulated colors to CIELab
c. Compute all pairwise Euclidean distances in Lab space
d. Record minimum distance
safe = TRUEFixing (when
fix = TRUE):colorspace::hex(colorspace::polarLUV(L, C, H))colorspace::sequential_hcl(n, palette = "viridis")and warnDependency:
colorspaceAdd to Imports. Provides CVD simulation, HCL conversion, and desaturation — one package handles both checking and fixing.
Files to create/modify
R/check_palette.Rtests/testthat/test-check_palette.RDESCRIPTIONcolorspaceto ImportsExample usage
Tests to write
safe = TRUEsafe = FALSEfix = TRUEreturns a palette that passes the checkget_palette())nparameter interpolates correctly before checkingseverity = 0always returns safe (no deficiency)