Draw a path through a perceptual color space, then have it graded on perceptual uniformity,
grayscale safety, and colorblind accessibility. The space is CAM02‑UCS — the same
one viscm and the makers of viridis used.
Part 1: build one freehand. Part 2: build a better
rainbow than jet. For open-ended exploring, there is also the
Guided Sandbox file.
Part 1 of 2 · freehand, no guides
Part 2 of 2 · build a better rainbow than jet
Your task
Click points into the color solid to drop colors, and they get joined into a path. Drag
them around until you think the ramp underneath looks like a good colormap. Then hit
Evaluate.
You get no help on this pass — no presets, no diagnostic views. Most people score
somewhere in the 40s to 60s the first time. That is expected and it is the point: find out
by feel what is hard about this before you are shown the instruments.
Build a better rainbow. On the plot are the control points of jet — the
most widely used and most criticized colormap in science. Your job is to move them
(add and delete them too) until you beat jet's score, without giving up its colorfulness.
The constraint is what makes this hard: the map still has to hit all the colors.
Anyone can beat jet by collapsing it to a smooth blue‑to‑yellow ramp — that
is Part 1's answer, and it scores well because the rubric there does not care about hue. Here
a fifth criterion, hue coverage, holds you to the rainbow.
So you are negotiating a real conflict: sweeping through every hue drags lightness up and
down and pushes colors out of gamut, which is exactly why jet fails. This is an open problem,
not a solved one. Every published rainbow scores between 50 and 60 on this rubric
— Google's turbo gets 59, and Kovesi's CET‑R1, the best of them,
gets 60 — because they all buy vividness by letting lightness run bright in the middle
and dark at both ends. Beat 70 and you are ahead of all of them.
You now have the instruments they used: the hue & chroma slice and the
lightness profile. The way through is usually to give up some saturation in
exchange for a lightness ramp that only ever climbs.
When you have something you are proud of, export it and use it on real data in the
companion notebook, colormap_making.ipynb.
You are scored on five things, and they
fight each other — that is the whole lesson:
30Perceptual uniformity Equal steps in the data must look like equal steps in color, or your
colormap invents structure that is not in the numbers. Scored mostly on the
derivative of the perceptual‑deltas curve — the second derivative of
perceived color along your path. A flat curve scores well; one that keeps changing slope
is rough no matter what its average is.
10Perceptual range The total of that same curve. A map that travels further through
perceptual space can resolve more distinct levels; a washed‑out one cannot.
25Lightness behavior Lightness should climb steadily (sequential) or form a clean symmetric
tent (diverging). This is what makes it readable in grayscale and orderable by eye.
15Hue coverage — "hit all the colors" What fraction of the hue circle your path actually visits. This is the
constraint that keeps Part 2 a rainbow instead of letting you retreat to a safe
two‑hue ramp.
25Colorblind accessibility Values far apart in your data must stay far apart in color for the
~1 in 12 men with red–green color vision deficiency.
10Gamut & smoothness Colors a screen cannot actually display get flattened, and kinked paths
show up as banding.
The color solid — CAM02‑UCS (J′ a′ b′)drag the background to orbit
Click empty space to add a point. Drag a point and it follows your cursor,
moving in the plane you are currently looking at — so orbit first, then drag
to control which direction you are moving in. Hold Shift while dragging
(or scroll over a point) to change lightness J′ only.
Your points split the colormap into equal shares. With 5 points, the path from
point 1 to 2 covers the first quarter of your data range, 2 to 3 the
next quarter, and so on — however far apart they are in color. So two points
placed close together spend a big slice of your data on almost no color change, and two
placed far apart cram a huge color jump into a small slice. Getting the spacing
right is most of what perceptual uniformity is asking of you.
Hue & chroma slice (a′b′)J′ = 50
Click to add a point, drag to move. Gray = no such color exists on a screen
at this lightness.
Lightness profile (J′)drag points up / down
For a sequential map this line should climb steadily and never turn back —
that is what makes it survive a black‑and‑white printout.
Keyboard: Tab next point, arrows nudge hue/chroma,
PgUp/PgDn lightness, Delete removes.
Live preview
Evaluation
—/ 100—
What it looks like
Your colormap
Printed in black & white
Moderate deuteranomaly (~50%) — the common case
Moderate protanomaly (~50%)
Deuteranopia (no green cone, ~6% of men)
Protanopia (no red cone, ~2% of men)
Tritanopia (no blue cone, rare)
Simulated with the Machado (2009) dichromacy matrices; the ~50% rows are
interpolated toward normal vision, so treat them as indicative rather than exact.
Perceptual step size
These are the two plots viscm shows. Each is the rate of
change along the map, so the dashed line sits exactly where a perfectly uniform colormap
would be flat. Every departure from that line is a place where your color scale is lying
about the spacing of your data.
Distance in CAM02‑UCS between neighboring colors. Spikes exaggerate that
part of the range; dips toward zero hide it.
The same thing for lightness alone. Dropping to zero means lightness has
stalled or turned around there.
Lightness J′ itself. Monotonic = survives grayscale printing and
reads correctly as "more".
The same data, three ways
That is your unaided score. Before you move on, look at the plots above and see whether you
can say in words what went wrong. Then take on Part 2: you get the diagnostic views,
and a harder brief — beat jet without giving up its colorfulness.
loads jet's control points onto the plot
Take it with you
The .jscm file stores all 256 of your colors exactly, so
python -m viscm view my_cmap.jscm will show precisely what you built. Note that
reopening it in viscm edit will not round‑trip a free‑form 3D path
perfectly, because that editor rebuilds lightness as a straight ramp.