Color Blind Safe Colormap Generator
Build sequential and diverging color scales for heatmaps and charts, scored on the one thing that actually decides whether they work: whether lightness keeps climbing after color vision is taken away.
The ramp, and what each viewer gets
Typical vision
Protanopia
Deuteranopia
Tritanopia
Achromatopsia
Squint at these, or look at them out of the corner of your eye. If a row still reads as a smooth run from one end to the other, lightness is doing its job. If a row looks like it has a bright or dark band in the middle, that band is not in your data.
This ramp holds up
Lightness climbs steadily and keeps climbing under every deficiency, including no colour vision at all.
Copy it out
background: linear-gradient(
90deg,
#E9F5FF 0%,
#C1E5FF 10%,
#94D5FF 20%,
#59C5FF 30%,
#1EB3F2 40%,
#00A1DB 50%,
#008EC2 60%,
#007BA9 70%,
#006991 80%,
#00587A 90%,
#16475F 100%
);Method
Lightness Is the Whole Game
One rule explains why viridis works, why jet does not, and why color blindness barely changes the answer.
A categorical palette needs colours that are mutually distinguishable, and it does not matter which one is “more”. A colormap is the opposite: it encodes a quantity, so a reader has to be able to order the colours at a glance. That demands something a palette never needs — lightness that climbs steadily from one end to the other.
This single requirement explains the famous failures. Jet and the rainbow colormaps wander up and down in lightness as they sweep through hue. The bright yellow band sitting between darker green and darker orange reads as a ridge, so people see boundaries in smooth data and miss real gradients where the ramp happens to flatten. That is a problem for everyone, before colour vision enters the picture at all.
Why this makes CVD almost a free win
A cone deficiency destroys hue separation and leaves luminance ordering largely intact. So a ramp built on lightness is already most of the way to being colour-blind safe — which is why the good colormaps were never really about colour blindness. They are about encoding magnitude honestly, and accessibility comes along for the ride.
“Largely” is doing real work in that sentence, which is why this tool measures instead of assuming. Protanopia darkens reds, because the missing long-wavelength cone contributes most of the luminance signal there. A red-anchored ramp that climbs perfectly for typical vision can flatten for a protanope. You cannot predict that by eye; it has to be simulated and checked, which is exactly what the rows above the verdict are doing.
Chroma gives way, lightness never does
Ramps here are built in CIE LCh with lightness interpolated linearly, so the ordering is correct by construction. sRGB cannot hold every combination — a very light colour simply cannot also be vivid — and the usual response is to clip the RGB channels. That quietly changes the colour's luminance and can break the very monotonicity the ramp was built to have. So when a colour will not fit, saturation is reduced until it does and the lightness is kept exactly.
| Measure | Good value | What it tells you |
|---|---|---|
| Types failing | 0 of 4 | Vision types where lightness stops climbing. Anything above zero means some readers cannot order your data. |
| Step evenness | Below 0.4 | How consistent the perceptual jump is between neighbouring stops. High values mean some parts of your range look more different than they are. |
| Smallest step | Well above 0 | The tightest gap anywhere in the ramp. Near zero is a flat band — a stretch of your data that all looks the same colour. |
| Verdict | Good | Good means it survives all four types including total colour blindness. Usable means one rough edge. Poor means it will mislead people. |
Limits
Use Viridis Unless You Have a Reason Not To
This tool will happily tell you that an established colormap beats the one you just made.
Viridis, cividis and the ColorBrewer scales were designed with perceptual research behind them and tested far more thoroughly than anything generated in a browser. If you have no constraint pushing you elsewhere, use one of them. They are better defaults, they are already built into matplotlib, R, D3 and Plotly, and nothing here is trying to replace them.
What this is for is the case where you do have a constraint: a brand palette, a house style, a chart that has to sit beside other elements in a specific hue. Then the question stops being “which famous colormap” and becomes “can I build one in this hue that still encodes magnitude honestly”. That is answerable, and the verdict above answers it — including when the answer is no.
Two things the score deliberately does not cover. It says nothing about how many distinct levels a reader can actually resolve, which depends on the size of your marks, the display and the viewing distance; a ramp that is fine for large filled regions can be useless for thin lines. And it says nothing about simultaneous contrast — identical colours look different against different surroundings, which no measure of the ramp alone can capture.
Finally, a smooth continuous ramp is often the wrong tool entirely. Binning data into a handful of clearly separated steps is easier to read than a gradient for most quantitative tasks, because people are far better at matching a colour to a key than at judging where it sits on a continuum.
FAQ
Colormap Questions
What people ask about color scales for quantitative data.
What is wrong with the rainbow and jet colormaps?
Their lightness goes up and down instead of climbing steadily. The bright yellow band between darker green and darker orange reads as a ridge, so readers perceive boundaries in smooth data and miss real gradients where the ramp flattens. That misleads everyone, not only colour blind readers — colour vision deficiency simply makes an already broken ramp worse.
How is this different from the palette generator?
A palette is a set of categories where no colour is “more” than another. A colormap encodes a quantity, so readers must be able to order it, which makes lightness the controlling factor. Different problem, different tool. Our palette generator covers the categorical case.
Should I just use viridis?
Usually, yes. Viridis and cividis were built on perceptual research, are more thoroughly tested than anything generated here, and ship with matplotlib, R, D3 and Plotly already. Reach for this tool when you have a constraint they cannot satisfy — a brand hue, a house style, a chart that has to match surrounding elements — and use the verdict to check whether your version still encodes magnitude honestly.
Why does my red ramp fail for protanopia specifically?
Because the long-wavelength cone that protanopes lack contributes most of the luminance signal in the red part of the spectrum. Take it away and reds darken relative to everything else, which compresses or reverses the lightness gradient your ramp depends on. Moving the hue away from pure red, or widening the gap between the light and dark ends, usually fixes it.
Is diverging or sequential right for my data?
Sequential when the data runs low to high with no special middle — population, rainfall, revenue. Diverging when there is a meaningful centre that readers should be able to find instantly: zero, an average, a target, a before-and-after difference. Using diverging for data with no real midpoint invents an emphasis that is not in the numbers.
Can I use red-to-green if the lightness is right?
Surprisingly often, yes — and the tool will tell you so rather than refusing on principle. A red-to-green diverging ramp that runs dark red through a light neutral to dark green survives every vision type, because the ordering lives in lightness rather than hue. What fails is red-to-green at constant lightness, which is the version people usually build.
How many stops should I export?
For a continuous gradient the eleven exported here interpolate smoothly in matplotlib, D3 and CSS. For most quantitative charts, though, binning into five to seven clearly separated steps is easier to read than a gradient, because matching a colour to a key is a much easier task than judging position on a continuum.