Analog Thermometer Graphics as a Mapped Temperature Scale

A PHP GD thermometer maps Cumulus temperature onto a min/max scale with an ice-point mark. Decorative scales that distort the observation are a fault.

Back to Cumulus weather software guides

An analog-style thermometer graphic is not a second copy of the temperature number. It is a map: one Cumulus observation (usually <#temp>) is placed on a declared numeric range, often with a mark at the ice point of water. PHP GD draws the tube, the fill, and the ticks. The historical TNET URL /projects.phpgdthermometer—a dotted path, not a slash—was that mapper for Cumulus stations.

The scientific risk is the decorative scale. If the tube’s geometry does not match the range you printed, or if the ice-point mark sits at a convenient pixel rather than at 0 °C / 32 °F, the picture contradicts the observation. This article is about the mapping, the ice point, and those failure modes. It is not an 80×80 avatar and not a 468×60 banner.

Historical context

Station sites liked a tall, narrow PNG that looked like a glass thermometer in a sidebar. Cumulus supplied the scalar and the unit token. GD drew a tube whose fill height tracked the value. Some renderers also painted today’s high and low (<#tempTH>, <#tempTL>) as ticks.

TNET does not rehost the historical PHP, the glass artwork, or a ZIP of thermometer skins. The mapping problem does not need the old code: choose a range, choose a linear (or honestly declared nonlinear) rule, mark the ice point, and refuse to let chrome invent a different temperature than the packet.

The URL spelling /projects.phpgdthermometer is historical. Neighboring banner and avatar projects used slash paths. Do not “fix” the dot; incoming links used it.

A thermometer is a scale, not a digit

A banner writes 21.4 C. A thermometer places 21.4 on an axis. Placement has extra degrees of freedom that digits do not:

  • Minimum of the visible scale. What temperature sits at the bottom of the tube?
  • Maximum of the visible scale. What temperature sits at the top?
  • Linearity. Equal degrees equal equal pixels, or not?
  • Reference marks. Ice point, maybe boiling point at standard pressure, maybe today’s extremes.
  • Clip behavior. What happens when the observation is off-scale?

Until those five are stated, the mercury column is a mood. Mood is not an observation.

The quantity being mapped must be named. Outside air temperature (<#temp>, realtime field 3) is the default. Indoor temperature (<#intemp>), apparent temperature (<#apptemp>), wind chill (<#wchill>), heat index (<#heatindex>), and MX feels-like (<#feelslike>) are different physical or derived quantities. Painting a “feels like” value on a tube labeled as if it were a dry-bulb sensor is a category error. If you map a derived index, the caption must say so.

Range is a scientific choice

The range is not artwork. It is the domain of the map.

Fixed climate range. Example: −30 to 50 °C, or −20 to 120 °F. Every frame uses the same axis, so mid-tube always means the same temperature. That is the honest default. The cost is resolution: a 1 °C change on an 80-degree axis is a few pixels.

Today’s min/max as the axis. Using <#tempTL> and <#tempTH> as the ends makes the column a fraction of today’s range. That is a useful derived display only if you label it that way. If the printed scale still looks like −20 to 40 while the fill is normalized to 8–19 °C, the picture is false. Today’s extremes also move during the day, so frames become incomparable.

Auto-ranging around the current value. A tube that recenters so the mercury is always “interesting” destroys the ice-point mark and makes screenshots incomparable.

Pick one rule and print the end ticks with numbers and <#tempunitnodeg>. A tube with no numbers is a decorative cylinder. Pixel resolution follows from range and height: a 200 px tube over 80 °C is 2.5 px per degree. Do not imply tenths in the column if a tenth is a fraction of a pixel. The numeral, if printed, can carry logger precision; the column cannot.

The ice-point marker

The ice point of water is 0 °C, which is 273.15 K on the ITS-90 scale used for the kelvin, and 32 °F on the Fahrenheit scale that many US stations still publish. That mark is the one reference a casual reader can check without knowing your climate.

Place it by the same mapping as the mercury, not by eye. On a linear −20 to 40 °C tube, 0 °C is one-third of the way up from the bottom, not “near the bottom because cold is down.” On a 0 to 100 °F tube, 32 °F is 32% of the span, not a pretty notch at 25% because the artwork had a bulb there.

If the visible range does not include the ice point—for example a tropical 10 to 45 °C tube—either omit the ice mark or change the range. A floating snowflake on a scale that never reaches freezing is decoration.

Do not mark 32 on a Celsius tube or 0 on a Fahrenheit tube. The packet’s unit token decides which ice-point number is correct. Switching palettes in a gallery without switching the mark is a unit bug.

Boiling point at standard atmospheric pressure (100 °C / 212 °F) is optional and usually off-scale for air-temperature graphics. Including it on a meteorological thermometer compresses the weather range into a sliver of the tube. Skip it unless you are teaching the scale rather than displaying a station.

How decorative scales distort the observation

These are the failure modes that made analog weather art untrustworthy:

Nonlinear glass. A real liquid-in-glass thermometer is close to linear in the stem if it is well made; the bulb is not part of the scale. Digital art often widens the column at the bottom for a “bulb” and then continues the fill into that bulb. The extra pixels in the bulb are not extra degrees. If fill height is counted from the bottom of the bulb, low temperatures are stretched and high temperatures are compressed. Map from the stem zero, or treat the bulb as chrome with no data.

Tick labels that do not match the map. Fancy fonts place “10” and “20” at positions that look even on the PNG while the fill uses a different origin. Verify by computing pixel position from the same function that draws the column.

Color substituting for height. A column that is always full, with color from blue to red, is a heatmap, not a thermometer. Heatmaps need a printed color legend. Without one, hue is not a quantity.

Clipping without a flag. If 41 °C is off a 40 °C scale and you fill to the cap, the picture says “at the top” which the reader hears as “hot” but not “off-scale.” Draw a cap marker or print > at the maximum.

Missing values as empty or as zero. An empty tube reads as “very cold” or “broken glass.” A full-to-ice-point tube reads as freezing. Missing Cumulus fields must not map to 0 °C. Fail to a blank stem and a -- numeral.

Siting bias drawn as precision. A thermometer graphic cannot correct a sensor over asphalt. It can only avoid adding a second bias in the scale.

Relationship to avatar and banner

An avatar prints one compact numeral. A thermometer shows where that numeral sits. Use a thermometer when the question is “how close to freezing?” or “where in this climate range?” Use an avatar when the question is “what is the number in a signature?” Use a banner when you also need wind and a name. Combining all three in one PNG reintroduces the density problem the three URLs were meant to separate.

If you print the numeral next to the tube, the numeral is the observation; the tube is a derived visual. They must agree to within the pixel resolution of the map. A tube at 0 °C next to a printed 32 F is a unit mismatch, not a cold snap.

What still applies

Linear axes, declared ranges, and a correctly placed ice point still apply whether the renderer is GD, SVG, or canvas. MX can feed the same <#temp> through JSON; the mapping does not care. Old GD code that assumed PHP 5 is a poor thing to execute, and it is not restored here.

A mapped scale must not contradict the source field. TNET’s public note on source identity, units, and quality is data sources and methodology. How temperature sits among other atmospheric families is evidence families. The Cumulus hub indexes related pages. Bind the scalar with the web-tag vocabulary.

Sources