Instruments 9 min
Ridges that are not there
A rainbow colormap invents features your data does not contain. Persistent homology turns that complaint into a count.
Everyone in scientific visualization has heard that the rainbow colormap is bad. The usual argument is aesthetic or vaguely perceptual: it is garish, it is not perceptually uniform, Nature asked people to stop. All true, and none of it is a measurement.
Here is the version with a number attached: a rainbow colormap causes viewers to see boundaries and ridges in data that has none, and you can count how many.
Where the phantom features come from
A colormap is a path through color space, parameterized by your scalar value. What a viewer perceives as structure — an edge, a band, a ridge — corresponds to places where perceived lightness changes rapidly, and especially where it changes direction.
Viridis is designed so lightness rises monotonically from one end to the other. Every step up in your data is a step up in lightness. There is exactly one perceptual “peak,” at the top of the scale, and it corresponds to the real maximum of your data.
Jet is not monotonic. Its lightness rises into cyan, falls through green, rises again into yellow, and falls into red. Two local maxima and a local minimum, none of which exist in your data.
Map a perfectly smooth linear ramp through jet and viewers report banding at the cyan and yellow transitions. The data has no bands. The colormap put them there.
Counting them properly
The naive approach is to count local maxima in the lightness profile. That fails immediately: any real profile has dozens of tiny wobbles from quantization and interpolation, and counting them gives a number dominated by noise rather than structure.
The right tool is persistent homology, and the intuition is worth stating without the machinery.
Imagine flooding the lightness profile from above. As the water level descends, peaks emerge as islands. Two islands eventually merge when the water drops below the saddle between them. Record, for each island, the level where it was born and the level where it merged into an older island. The difference is that feature’s persistence.
A tiny wobble is born and dies almost immediately — low persistence, and it is noise. A genuine perceptual peak survives a long descent before merging — high persistence, and it is structure a viewer will actually see.
The implementation is a union-find over the sorted samples, applying the elder rule: when two components merge, the younger one dies and the older survives. That is a few dozen lines, and it converts “jet is bumpy” into a ranked list of features with magnitudes attached.
Set a persistence threshold and the count becomes meaningful. Viridis reports one feature — the real one. Jet reports several, and each one is a place where readers of your figure will see a boundary you did not put in your data.
The part that matters more than the count
The audit runs the whole analysis once per observer model: normal vision, and each declared color vision deficiency.
This is where colormaps that look fine start to fail. A map can be perfectly monotonic in lightness for normal vision while developing extra topological features under deuteranopia, because the simulation changes which colors are distinguishable and therefore changes the perceived lightness path. The result is a figure that is honest for most readers and quietly misleading for others.
That failure mode is invisible to any check performed with normal vision only, which is nearly all of them. Reporting the feature count per observer makes it a property of the colormap rather than a property of who happened to look at it.
What it is for
The concrete use is auditing a corpus. Point the tool at every colormap in your plotting library and get a table: how many phantom features each one introduces, for each observer, with persistence values. That table is a piece of evidence, not an opinion, and it survives the argument that begins “but I like jet.”
It is also useful in the other direction. If you are designing a colormap, the persistence count is an objective function. A good map has exactly as many high-persistence features as your data does — usually one, at the extreme.
Limits worth stating
The threshold is a judgment. Persistence gives every feature a magnitude; deciding which magnitudes matter perceptually requires a cutoff, and that cutoff is an engineering choice rather than a fact about vision. The tool reports the persistences so you can apply your own.
Lightness is not all of perception. The analysis runs on a lightness profile, which captures most of what drives perceived banding but not all. Chroma and hue transitions contribute too, and this instrument does not model them.
Observer models are models. The per-observer analysis inherits every limitation of the CVD simulation underneath it.
A clean audit is not proof of a good colormap. Zero phantom features means the map does not invent structure. It says nothing about whether the map is legible in print, or usable at small sizes, or distinguishable from your background.
What the instrument does is turn one specific, real, widely-repeated complaint into a measurement that can be checked. That is a narrower claim than “this colormap is good,” and it is the claim that can actually be defended.