Validates a categorical chart palette before you ship the chart.
Colourblind-safety is arithmetic, not taste, so this runs the arithmetic: every pair of colours is compared in OKLab under full-colour vision and under simulated protanopia, deuteranopia and tritanopia, and every colour is checked for WCAG contrast against the surface it will actually sit on.
{
"colors": ["#1f4e79", "#e8c547", "#8b1a1a"],
"surface": "#ffffff",
"pairs": "adjacent",
"min_cvd_delta": 8.0,
"min_normal_delta": 15.0,
"min_contrast": 3.0,
"proof_sheet": true
}pairs: "adjacent" compares neighbours in assignment order, which is what a reader
compares when series sit next to each other. pairs: "all" compares every combination,
which is the right check when a filter can leave any two series alone together.
ok, a fixed-width summary table, per-colour swatches, per-pair pairs, and
failures / warnings written in plain language with the fix stated. With
proof_sheet: true you also get an SVG showing the palette in all four vision types.
A pair FAILs when full-colour separation drops below min_normal_delta or any simulated
dichromatic separation drops below min_cvd_delta. Contrast against the surface WARNs
rather than FAILs, because a direct label or a table view can carry identity where colour
alone cannot.
- sRGB transfer function and relative luminance: WCAG 2.1 / IEC 61966-2-1
- OKLab: Bjorn Ottosson, A perceptual color space for image processing (2020); ΔE is Euclidean distance in OKLab scaled ×100 so the numbers read like CIE ΔE
- Colour-vision-deficiency simulation: Machado, Oliveira and Fernandes (2009), severity 1.0, applied in linear light
python3 test_palette.py
No dependencies beyond the standard library for the colour maths.