Appearance
An accessible colour palette for data visualisation is one that stays distinguishable under colour-vision deficiency, meets WCAG contrast thresholds, and never carries meaning by colour alone. The practical route is to start from a tested palette — Okabe–Ito for categories, Viridis or Cividis for sequences — add a redundant channel like shape or label, then verify with a colourblind simulator and a greyscale check. This guide walks the full workflow for historians.
What makes a palette accessible?
Roughly 1 in 12 men and 1 in 200 women have some colour-vision deficiency, and many readers will see your chart printed in greyscale or on a poor screen. Three rules cover almost everything:
- Distinguishable under red–green and blue–yellow deficiency.
- Sufficient contrast — WCAG 2.1 asks for at least 3:1 for graphical objects and 4.5:1 for normal text.
- Never colour alone — pair colour with shape, label, or pattern.
Meet all three and the chart works for everyone, including the future reader looking at a photocopy of your article.
Which palettes can you just use?
Do not invent palettes by eye — start from tested sets:
| Palette | Type | Use it for |
|---|---|---|
| Okabe–Ito | Qualitative (8 colours) | Distinct categories, e.g. regions |
| ColorBrewer (CB-safe) | Qual / sequential / diverging | General-purpose, well documented |
| Viridis / Cividis | Sequential | Heatmaps, density, magnitude |
| Magma / Inferno | Sequential | High-contrast magnitude |
| Paul Tol sets | Qual / diverging | Print-safe, carefully balanced |
Cividis is especially good for history because it is engineered to look nearly identical to colourblind and non-colourblind readers.
How do you apply one in code?
In Python with matplotlib, switch to a perceptually uniform map in one line:
python
import matplotlib.pyplot as plt
# Sequential heatmap of record density
plt.imshow(grid, cmap="cividis") # not "jet" / "rainbow"
# Qualitative categories with Okabe-Ito
okabe_ito = ["#E69F00", "#56B4E9", "#009E73", "#F0E442",
"#0072B2", "#D55E00", "#CC79A7", "#000000"]
for i, region in enumerate(regions):
plt.plot(region.x, region.y, color=okabe_ito[i], label=region.name)In R, scale_colour_viridis_d() and the ggokabeito package give the same palettes inside ggplot2 with one added line.
Why avoid the rainbow colourmap?
The classic rainbow (jet) map is not perceptually uniform: equal steps in your data become unequal steps in perceived colour, inventing sharp bands where the data is smooth and hiding detail where it matters. It also collapses badly for colourblind readers. For any heatmap of record density, price, or population, replace it with Viridis, Cividis, or Magma. This single swap improves both accuracy and accessibility.
How do you verify the result?
Never ship on trust — simulate and test:
- Run the chart through Color Oracle or Coblis to preview deuteranopia, protanopia, and tritanopia.
- Desaturate to greyscale — if categories blur together, add a redundant channel.
- Check text and key-mark contrast ratios with a WCAG contrast checker.
The greyscale test is the quickest single check; it catches colourblind and print problems in one glance.
Adding redundancy beyond colour
Colour should reinforce, not solely carry, a distinction. For line charts give each series a different dash pattern and a direct end label; for scatter plots vary marker shape; for maps add hatching or labels to filled regions. This redundancy is also what lets your figure survive being screenshotted, recoloured by a CMS, or reprinted in black and white years later — exactly the durability a historical record deserves.
Key Takeaways
- Accessible palettes are distinguishable under colour-vision deficiency, high-contrast, and never colour-only.
- Start from tested sets: Okabe–Ito for categories, Viridis/Cividis for sequences.
- Drop the rainbow/jet map in favour of perceptually uniform sequential maps.
- Add a redundant channel — shape, dash, label, or pattern — to every colour distinction.
- Verify with a colourblind simulator and a greyscale check, plus a WCAG contrast test.
- Redundancy also makes figures durable to recolouring and black-and-white reprinting.
Frequently Asked Questions
What makes a colour palette accessible for data visualisation?
An accessible palette stays distinguishable for people with colour-vision deficiency, keeps text and key marks above WCAG contrast thresholds, and never encodes meaning by colour alone, so a colourblind or greyscale reader loses no information.
Which colourblind-safe palettes can I use off the shelf?
Reliable choices include ColorBrewer's colourblind-safe schemes, the Okabe–Ito eight-colour qualitative set, Viridis and Cividis for sequential data, and Paul Tol's palettes, all designed and tested for colour-vision deficiency.
How do I check whether my chart works for colourblind readers?
Simulate deuteranopia, protanopia, and tritanopia with a tool such as Color Oracle or Coblis, and additionally view the chart in greyscale, which catches both colourblind and print-reproduction problems at once.
Should I use a rainbow (jet) colourmap for historical heatmaps?
No, the rainbow/jet colourmap is not perceptually uniform and creates false boundaries and lost detail; use a perceptually uniform sequential map like Viridis, Cividis, or Magma instead.
How do I make colour-coded categories accessible beyond colour?
Add a redundant channel such as shape, line style, direct text labels, or pattern fills, so the distinction survives colourblindness, greyscale printing, and low-quality screens.