FORECASTEAGLE.COM · NOAA / NWS DATA · NORTH AMERICA HOMERRFSHRRRRTMAGFSNDFDNBMALERTSMODELSNOTESCOLOURSBUILDERSTATUSABOUT

ABSOLUTE COLOUR SCALES, AND THE PROBE THAT READS A PIXEL BACK

A map is a picture of numbers. It should give them back.

Colour is where weather graphics most often lie, and rarely on purpose. The commonest failing of auto-generated model graphics is a ramp that re-fits itself to each frame's minimum and maximum, so a loop shows the palette rescaling rather than the weather changing: a mild afternoon and a heatwave both span the full ramp and look alike. Everything this site draws is anchored to absolute values, never to a frame. 32 °F is the same pale blue on every page, every cycle, every model, and an animation that reddens is one that really is warming.

That is the first principle on the About page. The rest of this note is what follows from taking it seriously.

The palettes are choices

The NWS's own public maps are the thing this site exists to improve on, so the palettes are deliberate rather than defaults. Reflectivity keeps the classic NEXRAD ramp: professionals read dBZ by colour from muscle memory, and inventing a nicer radar palette would cost more in legibility than it gains in looks. Continuous fields — temperature, dewpoint, wind — use ramps that stay monotonic in lightness, so they survive greyscale printing and do not produce the false banding a rainbow ramp creates at the cyan and yellow transitions. Relative humidity is the dewpoint ramp's own family, browns through greens to teal, because the two fields are read together and a reader should not have to learn a second vocabulary of colour to compare them. Visibility runs backwards on purpose: the alarming end is low.

The ramps are shared across products, which is the point. NBM and NDFD use the same tables for the same quantities, so a value that reads 87 on one page is the same colour on the other, and any difference you see flipping between tabs is a difference in the forecast, not in the rendering. The GFS extends the national temperature and dewpoint ramps outside their range — Antarctica in August runs below −80 °F and the shared table bottoms out at −40 — but only adds stops outside the shared span, so between −40 and 120 the GFS is coloured bit-for-bit as the CONUS models are.

The picture is an encoding

The maps are colour-mapped PNGs, so the browser holds colours and no numbers. City labels answer that for places: every frame ships a value sampled at each labelled city. The pointer readout answers it for anywhere, and it does so without publishing an extra byte per frame.

Every raster is drawn through a fixed 128-entry palette, which makes the picture an invertible encoding of the field: sample the pixel under the cursor, find the palette entry it came from, read the value back out. Each field publishes that exact palette alongside its frames — 512 characters of base64 — so the browser inverts the very bytes that were drawn, rather than rebuilding the ramp from the legend stops and trusting two languages to interpolate identically forever. Drift there would be invisible — a readout quietly off by a degree — and here it cannot happen.

Sampling is one texel, not one raster. The obvious implementation draws the frame to a canvas and reads it back, which at a global raster's size is tens of megabytes held for a number in the corner. Instead each query blits a single pixel into a one-by-one canvas with smoothing off, so a lookup costs well under a millisecond and runs on every movement of the mouse. A tap does the same on a touch screen, and the value stays put.

Exactly as precise as the picture

The readout is as precise as the picture and no more: one part in 127 of the ramp's range. Taking the midpoint of each palette step rather than its lower edge halves the worst case:

fieldstepworst-case error
Temperature (−40 to 120 °F)1.26 °F±0.63 °F
Reflectivity (5 to 75 dBZ)0.55 dBZ±0.28 dBZ
Wind (0 to 100 mph)0.79 mph±0.39 mph

So a probe can disagree with a city label by a unit in the last place — the label is sampled from the model grid, the probe from the drawn image — and that disagreement is honest. Raising the palette to 254 levels would halve it again, but measured on real frames that costs 27 to 31 percent on every PNG, around 250 MB across the site, which is not worth a third of a degree. A banded table, like the ECMWF ecCharts style, maps many values to one colour, so inversion can only recover the band; the readout then says "20 to 22 °C", which is all the chart itself claims.

Changing the colours without changing the numbers

Because the rasters are palettised, a colour table is a choice at view time rather than a second copy of every frame. The palette is 387 bytes inside a 519 kB file; rewrite that chunk and the same bytes decode in a different palette, with the image data untouched, bit for bit. The RRFS, HRRR and GFS viewers do this in the browser.

What makes that honest is that the value axis is preserved rather than restretched. Palette index i means the same value it always did, because that is what was drawn and what the probe inverts — so a new ramp is sampled at the field's own levels, clamping where it is narrower and cropping where it is wider. What you never get is a picture whose colours imply a scale the data does not have. Three things move together on a switch, or the map starts lying: the palette in every frame, the probe's copy of it, and the legend. And ramps are offered by units — a °F table appears on temperature and dewpoint and nowhere else, because a dBZ ramp across a temperature axis produces a plausible map that means nothing.

The library behind that is 1,128 tables from nine sources — NASA GIBS, the AWIPS pack, NASA's GMAO weather maps, ECMWF ecCharts, the NCAR ensemble charts, College of DuPage, NOHRSC and Ryan's own GrADS tables — all browsable in the gallery, with a builder for trying a new one on a real forecast hour. Only some declare units; the rest name themselves by product and are applied in normalised mode, their span stretched across the field's, and the menu says which is which. Only the first kind is a statement about values.

No invented resolution

The last principle is the one you can see without a probe. Model grids are drawn at their true spacing, so zooming in reveals real 3 km cells rather than a smooth interpolation the model never produced. A smoothed map looks more confident than the model is, and confidence the model does not have is not something a map should add. Every field states its model, cycle and valid time, so any number — read from a label, or off a pixel — can be traced back to the NOAA file it came from.