Scientific Computing · Scientific Visualization
Perceptually Uniform Colormaps and the Failure of Rainbow Ramps
How a scalar field becomes color through a lookup table, why monotonic lightness and equal perceptual steps are the two constraints that matter, and where banding and false contours come from.
A scalar field is an array of numbers, and nothing in that array is visible. Making it visible means composing the field with a function that maps each value to a color, and almost every property that makes the resulting image readable or actively misleading belongs to that function rather than to the data. Two images of the same grid can support opposite conclusions because one of them used a ramp whose luminance rises and falls.
The mapping is usually implemented as a one-dimensional table sampled from a curve through a three-dimensional color space. Once it is written that way, the questions become geometric: how long is the curve, does its luminance increase monotonically, is arc length proportional to the parameter, and does the curve close on itself. Those four questions separate a colormap that can be read quantitatively from one that only decorates.
A lookup table is a curve sampled at 256 points
The common implementation stores 256 RGB triples, three bytes each, 768 bytes in total, twelve cache lines on the usual 64-byte line size. A field value is normalized to $[0,1]$, multiplied by 255, and truncated to an index. The table lookup itself is therefore free compared with the interpolation that produced the value, which is why the table is the standard representation even on hardware that could evaluate a spline.
The consequence of an 8-bit table driving an 8-bit display is that the data range is divided into 255 intervals regardless of how much data lies inside the range. A field with a long tail spends most of its table on values that occur rarely, and the dense part of the distribution collapses into a few indices. This is a property of quantization, not of the colormap, and it explains why the same ramp looks smooth on one dataset and stepped on another. Where the ramp’s color changes slowly in perceptual terms, adjacent indices are indistinguishable and the field appears to have plateaus. Where it changes fast, adjacent indices differ visibly in a region of the data that may be physically featureless.
Alongside the table, an index-to-color mapping has two other decision points. The first is the interpolation space used to build the table from a small number of control points. Interpolating control colors directly in sRGB coordinates darkens and desaturates the middle of the ramp, because sRGB values are encoded with an approximately 2.2 power transfer function and averaging them is not averaging light. Interpolating in linear light, or in a perceptual space, produces the intermediate colors that a designer intended. The second is what happens at the ends. Clamping is the usual choice; wrapping is only correct for periodic quantities such as phase.
Lightness must be monotone, or the eye invents structure
Human vision extracts form primarily from luminance. Hue and chroma contribute to segmentation and category, but edges, ridges, and relative height are read from the luminance channel. A colormap whose lightness is monotonic makes the image an ordered scale: brighter means larger, everywhere, with no reversals. The visual system can then compare two regions without consulting a legend.
A colormap whose lightness rises and falls breaks that. A reversal in the derivative of luminance is an inflection, and lateral inhibition in the retina exaggerates luminance changes at inflections, the same mechanism that produces Mach bands at a soft gradient boundary. The result is a visible contour in the image at a location where the data has no contour. A reader who does not know the ramp will interpret that contour as a feature of the field.
The rainbow family fails this test by construction. Its hue path runs from blue through cyan and green to yellow and red, and perceived lightness peaks in the yellow and cyan region while dropping toward both ends. Two different values, one near the blue end and one near the red end, can have nearly the same luminance, so the ramp is not injective once hue information is removed, which is exactly what happens when the figure is printed in grayscale, photocopied, or viewed by a reader with a color vision deficiency. Red-green deficiency, commonly estimated at roughly one in twelve men of northern European descent and well under one percent of women, maps the red and green portions of the ramp onto similar hues, leaving a bright band in the middle and dark ends.
The ordering problem is separate from the luminance problem. A rainbow ramp does not tell the reader which end is high. The convention that red means hot is cultural and not universal, and in a field where red also encodes a warning or a material, the ramp’s direction becomes ambiguous. Sequential ramps solve this by making the ordering visible without a legend: dark to light, or light to dark, with the direction fixed by the surrounding figure conventions.
Diverging ramps are two sequential ramps around a neutral
Diverging data has a meaningful center, usually zero or a reference value, and the sign matters as much as the magnitude. The standard construction is a pair of sequential ramps joined at an achromatic midpoint, each arm monotone in lightness away from that midpoint. Reading the sign then requires only a comparison against the neutral color, and reading the magnitude requires the distance from it.
Two details decide whether the construction works. The midpoint must be at an extreme of lightness, typically the lightest value in the ramp, so that values near the center recede and values far from it advance. If the midpoint is a mid-lightness color, the ramp has two luminance humps and the center reads as a band rather than as zero. The second detail is symmetry: perceptual distance from the midpoint must be equal on both arms, or a value of +1 and a value of -1 will not look equally far from the center, and readers will judge the positive side as more extreme.
Cyclic quantities such as phase or orientation need a third construction, a ramp whose endpoints coincide. If the two ends differ, the wrap produces a visible seam wherever the quantity crosses the period boundary, and that seam moves as the data changes. A cyclic ramp with constant lightness and varying hue avoids the seam but loses the ordered lightness cue, which is acceptable for phase, where no ordering exists, and wrong for magnitude.
What the check looks like in code
A colormap can be validated without rendering anything. The test is to sample the table, convert each entry to relative luminance, and check that the sequence is monotone and that the largest step is not much larger than the median step. The conversion below uses the sRGB transfer function and the Rec. 709 luminance weights, the same numbers used for the relative luminance definition in WCAG 2.
import numpy as np
def srgb_to_linear(c):
c = np.asarray(c, dtype=float)
return np.where(c <= 0.04045, c / 12.92, ((c + 0.055) / 1.055) ** 2.4)
def relative_luminance(rgb):
r, g, b = srgb_to_linear(np.asarray(rgb, dtype=float)).T
return 0.2126 * r + 0.7152 * g + 0.0722 * b
def build_lut(stops, n=256):
# stops: (position, sRGB triple); interpolate in linear light, store sRGB
pos = np.array([s[0] for s in stops])
lin = srgb_to_linear(np.array([s[1] for s in stops]))
t = np.linspace(0.0, 1.0, n)
out = np.stack([np.interp(t, pos, lin[:, k]) for k in range(3)], axis=1)
return np.where(out <= 0.0031308, 12.92 * out,
1.055 * out ** (1 / 2.4) - 0.055)
def report(lut):
y = relative_luminance(lut)
d = np.diff(y)
monotone = bool(np.all(d >= 0)) or bool(np.all(d <= 0))
print(f"L range {y.min():.3f}..{y.max():.3f} monotone={monotone}")
print(f"max step {np.abs(d).max():.4f} median {np.median(np.abs(d)):.4f}")
For a ramp built this way from three control points, the report gives the two numbers that matter: the luminance span, which should be most of the available range, and the ratio of the largest to the median step, which indicates where the ramp will band. A large ratio at one end means the table spends many indices on a small perceptual change there and few where the image needs resolution.
The same check applied to a rainbow ramp fails the monotone test. That failure is the quantitative form of the observation that a rainbow image has bands.
Limits of the property
Perceptual uniformity is always uniformity with respect to a particular observer model and a particular viewing geometry. The CIE 1976 $L^*a^b^$ space is only locally uniform; its chroma and hue axes distort at high saturation, which is why later models such as CAM02-UCS and Oklab were built and why modern uniform ramps are designed in one of those spaces rather than in $L^*a^b^$. A ramp that is uniform under one model is approximately, not exactly, uniform under another.
Uniformity also does not transfer across scale. Judgments of color difference depend on the angular size of the patch, on the surrounding color, and on simultaneous contrast, so a uniform ramp placed next to a large saturated region will not read as uniform. Nor does a uniform ramp solve a poorly chosen mapping: if the data spans six orders of magnitude and the ramp is applied linearly, the image shows one color with a few bright outliers, and the fix is a logarithmic or histogram-equalized mapping of values to the parameter, not a different color curve.
The decomposition into these layers, values to parameter, parameter to color, color to pixel, is what makes the failure modes separable. A banded image can come from any of the three: a bad parameter mapping, a ramp with uneven perceptual steps, or an 8-bit path that cannot resolve the ramp’s slow regions. Separating them is easier than fixing the composite.
Colormaps also interact with the geometry of the field. A continuous ramp encodes magnitude, but a reader often needs boundaries, and the choice between a smooth ramp and a set of discrete contour bands is a choice about the task, not about color. Discrete bands with a uniform ramp inside each band, sometimes indexed by a legend of ranges, trade continuity for exact comparability. The next layer of the problem, how the scalar field is converted to geometry rather than color, is treated in Marching Cubes and the Case Table, and the question of where values exist between samples, which determines whether a ramp is evaluated on real data at all, is covered in Interpolation and Resampling of Scalar Fields.
References
- Good Colour Maps: How to Design Them — Peter Kovesi, arXiv:1509.03700
- The misuse of colour in science communication — Crameri, Shephard & Heron, Nature Communications, 2020
- ColorBrewer.org: An Online Tool for Selecting Colour Schemes for Maps — Harrower & Brewer, The Cartographic Journal, 2003
- Diverging Color Maps for Scientific Visualization — Kenneth Moreland, ISVC 2009