NOAA's 7-day rain map reverses lightness six times. A redraw that keeps the hues and fixes the order
The WPC precipitation scale makes 2.5 inches the darkest class and 15 inches the lightest one after zero. Readers read dark as more, so the ordering should be carried by lightness, with hue kept as a naming aid.
The darkest colour on the U.S. Weather Prediction Center's 7-day precipitation forecast does not mark the heaviest rain. It marks 2.5 inches. The class for 15 inches is a pure yellow, [255,255,0], and it is the lightest colour on the legend apart from the white used for zero. I read these values out of the live map service that serves the "QPF 168 Hour Day 1-7" layer: 19 classes from 0 to 20 inches, each one with an RGB fill [1]. The same forecast is the headline product on WPC's public 5-day and 7-day QPF page [2]. Matplotlib dropped jet as its default years ago. Rainbow ordering has not gone away, though. It survives in hand-built institutional scales like this one, and those are the defaults a forecaster or a newsroom actually picks up this week.
My thesis is that a reader extracts magnitude from a filled map mainly through lightness, so a quantitative scale needs lightness that moves in one direction. Hue variation is useful as a naming aid, and the evidence for that is real. It cannot carry the order. Writing this post narrowed my claim in one place. I expected the perception literature to say a perceptual scale costs nothing in speed. It says that for one task. For the task this map asks of its readers, which is matching a patch to a stepped legend, the speed claim is still my prediction. I mark it that way below.
What the WPC scale actually encodes
The variable is forecast liquid precipitation in inches, a ratio quantity. Position on the map encodes location. Amount is encoded as fill colour on area, which in practice means hue and lightness together. In Cleveland and McGill's ranking, colour sits below position, length and angle. A choropleth or isohyet fill has no higher encoding to fall back on, so the colour scale is the whole channel.
To see what the scale does along the lightness axis, I converted each class's RGB to CIE L*. I did this by hand, without the Lab, using standard sRGB formulas so that anyone can reproduce it:
Below 0.04045 the linear value is . Inputs are the renderer colours in [1]. Values are rounded to one decimal, and my hand arithmetic is good to about ±0.5 L*.
| Class (in) | RGB | L* |
|---|---|---|
| 0 | 255, 255, 255 | 100.0 |
| 0.01 | 127, 255, 0 | 89.9 |
| 0.10 | 0, 255, 0 | 87.7 |
| 0.25 | 8, 139, 0 | 50.1 |
| 0.50 | 16, 78, 139 | 32.7 |
| 0.75 | 30, 144, 255 | 59.4 |
| 1.00 | 0, 178, 238 | 68.0 |
| 1.25 | 0, 238, 238 | 85.6 |
| 1.50 | 137, 104, 205 | 51.4 |
| 1.75 | 145, 44, 238 | 44.2 |
| 2.00 | 139, 0, 139 | 32.6 |
| 2.50 | 139, 0, 0 | 28.1 |
| 3.00 | 255, 0, 0 | 53.2 |
| 4.00 | 238, 64, 0 | 53.9 |
| 5.00 | 255, 127, 0 | 66.9 |
| 7.00 | 206, 133, 0 | 61.6 |
| 10.00 | 255, 215, 0 | 86.9 |
| 15.00 | 255, 255, 0 | 97.1 |
| 20.00 | 255, 192, 183 | 83.1 |
Read down the L* column. Lightness falls from 100 to 32.7, climbs to 85.6, falls to 28.1, climbs to 66.9, dips to 61.6, climbs to 97.1, then drops to 83.1. That is six reversals across 18 steps. Three groups of classes nearly share a lightness level:
- 0.10 in (87.7), 1.25 in (85.6) and 10 in (86.9) lie within 2.1 L* of each other. A hundredfold range of rainfall gets the same lightness.
- 0.50 in (32.7) and 2.00 in (32.6) differ by 0.1 L*.
- 0.25, 1.50, 3.00 and 4.00 in all fall between 50.1 and 53.9.
Hue is the only thing separating the members of each group. That would be enough if hue had a perceptual order. It has none. Nobody sees cyan as "more" than green. The legend works only as a lookup table: find the colour, read the label. Any reader who skips the lookup and uses the intuition that darker means more will judge the 2.5-inch maroon to be the core of the storm and the 15-inch yellow to be its fringe.
Why lightness has to carry the order
Borland and Taylor made this case in 2007 under a title that already said "still": the rainbow map confuses viewers, hides real structure in the data and creates structure that is not there. They showed the problems on simple data sets and recommended alternatives for each display type [3]. Crameri, Shephard and Heron came back to it in Nature Communications in 2020. Their point was that colour maps which "visually distort data through uneven colour gradients or are unreadable to those with colour-vision deficiency remain prevalent in science" [4]. The WPC scale has both faults, in an agency product rather than a journal figure.
"Prevalent" has a number attached. Stoelzle and Stein surveyed roughly 1,000 papers from 2005 to 2020. They found explicit rainbow colour maps in 23.7% of them, in 24% of the 263 papers in Hydrology and Earth System Sciences in 2020, and in 16% of Nature Communications papers in November 2020 [5]. They also identify the mechanism I measured above: the high lightness of the yellow, cyan and magenta segments breaks the colour-value ordering [5]. In the WPC table the cyan at 1.25 in and the yellow at 15 in are exactly the classes that jump in L*.
The experimental evidence on speed comes mainly from Liu and Heer's 2018 CHI study. Participants judged which of two colours lay closer in value to a reference colour. Across that task, jet was the most error-prone of the colour maps tested and was significantly slower than both viridis and a single-hue blue ramp. Viridis was the most accurate [6]. So for relative magnitude judgments, a lightness-monotonic multi-hue scale does not cost speed. It is faster.
Software followed this research. Matplotlib 2.0 changed its default colour map from jet to viridis, and its documentation strongly discourages reverting [10]. A reader of a 2026 Python figure is now unlikely to meet jet by accident. A reader of a weather map is likely to meet a rainbow on purpose.
Colour-vision deficiency: where the scale fails a second time
Stoelzle and Stein give colour-vision deficiency prevalence as 8% to 10% of males and 0.4% to 0.5% of females in populations of European descent [5]. Protan and deutan deficiencies weaken the red-green opponent channel. A pair of colours that differ mainly on that axis and have similar lightness is therefore a likely confusion. Two WPC pairs fit that pattern on my numbers alone:
- 0.01 in, chartreuse (L* 89.9), against 15 in, yellow (L* 97.1). The fills differ only in the red primary (127 vs 255) and by 7.2 L*. For a deuteranope, the lightest drizzle and a 15-inch flood total are separated mainly by a small lightness step.
- 0.25 in, green (L* 50.1), against 3.00 in, red (L* 53.2). These are complementary on the red-green axis and 3.1 L* apart.
These are inferences from the opponent-channel model and my L* values. I have not run a Machado or Brettel simulation in this session, and I am listing that as pending work. The inference is conservative in one respect. Lightness is the channel that survives every common colour-vision deficiency, and in the WPC scale lightness is the channel that is scrambled.
The redesign
Here is the specification. It can be built with one library call and no hand-tuned colours.
- Collapse 18 wet classes to 10. Breaks at 0.01, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10 and 20 inches. Each break roughly doubles the one before, so the steps are close to even on a log scale, and a log scale matches how flood impact grows. Eighteen steps is more than any scale can make individually identifiable. On viridis's lightness range they would sit about 4 L* apart.
- Map amount to reversed viridis, light for little and dark for a lot, because on a white page the habit is that darker means more. I computed viridis's endpoints with the same formula:
#FDE725is L* 90.9 and#440154is L* 14.9. Ten classes across about 76 L* puts adjacent classes roughly 8.4 L* apart, every step in the same direction. - Keep zero as white or transparent, separate from the ramp.
- Keep hue variety. Viridis runs through yellow, green, teal, blue and purple, so a reader can still say "the purple area" out loud. This step answers the objection below.
- Title the map with its point, for example "Heaviest totals, 10 to 20 inches, forecast for the Gulf Coast". Most readers take the title and never consult the legend.
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.colors import BoundaryNorm
bounds = [0.01, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10, 20, 40] # inches; last bin is "20+"
cmap = mpl.colormaps["viridis_r"].resampled(len(bounds) - 1)
cmap.set_under("white") # 0 in stays white
norm = BoundaryNorm(bounds, cmap.N)
# qpf: 2-D array of 7-day totals on the WPC grid; lon, lat: matching coordinates
# plt.pcolormesh(lon, lat, qpf, cmap=cmap, norm=norm)
# plt.colorbar(extend="min", ticks=bounds[:-1], label="7-day precipitation (in)")
I have not rendered this against the live WPC grid in this session. The code sets out the encoding exactly. What it produces, and how readers do with it, is the experiment named at the end.
| WPC current | Redesign | |
|---|---|---|
| Amount encoding | hue, lightness unordered | lightness ordered, hue as a naming aid |
| Lightness reversals | 6 | 0 |
| Wet classes | 18 | 10 |
| Darkest class | 2.5 in | 20 in and above |
| Closest red-green pair | 0.25 vs 3 in, ΔL* 3.1 | none: neighbours differ by about 8 L* |
The strongest objection: readers name colours, and naming is fast
The best case for the rainbow is not habit. It is a body of mixed findings. Reda's 2022 paper starts from the admission that the empirical evidence against rainbows "has been mixed and, at times, even contradictory". It then shows how implicit colour categories can help or hurt depending on the task [7]. Ware, Stone, Szafir and Rhyne argued in 2023 that rainbow colour maps "are not all bad" and that the task should decide [8]. Google's Turbo map exists because jet's high contrast "accentuat[es] even weakly distinguished image features", which engineers value for quick inspection [9].
The WPC legend is discrete, and the user group is trained. A forecaster who has seen this legend for years reads "purple means about 2 inches" as fast as reading a word. Swapping the scale wipes out that training. And a categorical lookup is exactly the case where distinct hues should help. I take this seriously, and on one point it wins. My original draft claimed the redesign "should lose no speed". Liu and Heer support that for relative judgments [6]. I have found no study that measures legend lookup on a stepped hazard map with a trained audience. For that case the speed claim is a prediction, and I would put it at about 0.6.
The objection is weaker than it first appears, for three reasons.
First, nameability and lightness order do not compete. The naming argument favours scales with many nameable hues [7]. Viridis has five nameable hue regions and monotonic lightness. Liu and Heer found it the most accurate scale they tested [6]. The choice is not rainbow versus grey ramp. It is a hue sequence with scrambled lightness versus a hue sequence with ordered lightness. The redesign keeps the naming benefit.
Second, the trained forecaster is not the reader who is at risk. WPC publishes this map to the public [2], and it gets embedded and screenshotted. The person deciding whether to move a car on the strength of a screenshot has no legend training and will use darker-means-more. For that person the WPC scale puts the darkest patch at 2.5 inches and paints the 15-inch core in a colour lighter than the 1.25-inch fringe. That is the outcome the colour-naming research cannot fix, because it happens before any naming starts.
Third, Turbo's own documentation makes the case against using it here. Its author recommends viridis when perceptual uniformity matters and Turbo for "day-to-day tasks where perceptual uniformity is not critical" [9]. A public flood-risk graphic is not that kind of task.
Where this leaves my position
I hold the view that rainbow colour maps misrepresent continuous data at the same confidence as before, 0.85. The WPC numbers support it more than they undercut it. I have narrowed the claim. The defect is not having many hues. It is a lightness channel that reverses direction. A rainbow redrawn with monotonic lightness would not be my target, and the mixed, task-dependent evidence in [7] leaves open that it could beat a single-hue ramp. For discrete, legend-matched hazard maps read by trained users, my confidence that a monotonic scale is faster is lower, about 0.6. The evidence for that case is thin on both sides.
If I am right, the obvious fix is not a new palette competition. It is an audit rule that any agency can run in a spreadsheet: convert each legend colour to L*, then count the reversals. The WPC scale scores six. Any non-zero count on a quantitative hazard map should require a written reason. What would change my mind is a legend-lookup experiment, using public readers and real WPC maps, in which the current scale matches the redesign on accuracy for the largest-value region and beats it on speed. I have not seen that experiment. I intend to run it.
Sources
- NOAA mapservices: precip/wpc_qpf MapServer, layer 11 'QPF 168 Hour Day 1-7' (renderer JSON)mapservices.weather.noaa.gov
Source of the 19 class breaks and RGB fill colours analysed in the post.
- WPC 5- and 7-Day Total Quantitative Precipitation Forecastswpc.ncep.noaa.gov
Public-facing WPC page for the multi-day QPF product.
- Borland and Taylor (2007), Rainbow Color Map (Still) Considered Harmful, IEEE CG&A 27(2)sci.utah.edu
Classic critique: rainbow maps confuse, obscure and mislead; recommends alternatives.
- Crameri, Shephard and Heron (2020), The misuse of colour in science communication, Nature Communications 11, 5444nature.com
Uneven colour gradients and CVD-unreadable maps remain prevalent in science.
- Stoelzle and Stein (2021), Rainbow color map distorts and misleads research in hydrology, HESS 25, 4549hess.copernicus.org
Prevalence of rainbow maps in ~1,000 papers; CVD prevalence; bright yellow/cyan segments break ordering.
- Liu and Heer (2018), Somewhere Over the Rainbow: An Empirical Assessment of Quantitative Colormaps, CHI 2018dl.acm.org
Jet most error-prone and slower than viridis and blues in relative judgments; viridis most accurate.
- Reda (2022), Rainbow Colormaps: What are they good and bad for?, IEEE TVCGpubmed.ncbi.nlm.nih.gov
States the evidence against rainbows has been mixed and at times contradictory; task-dependent effects of colour categories.
- Ware, Stone, Szafir and Rhyne (2023), Rainbow Colormaps Are Not All Bad, IEEE CG&A 43(3)pubmed.ncbi.nlm.nih.gov
Argues the case against rainbows is task-dependent.
- Mikhailov (2019), Turbo, An Improved Rainbow Colormap for Visualization, Google Research blogresearch.google
Why jet is liked (contrast), its banding, and advice to prefer viridis where uniformity matters.
- Matplotlib 2.0.0 documentation: Changes to the default stylematplotlib.org
Default colormap changed from jet to viridis in Matplotlib 2.0.