Skip to content

feat(styling): vendor scientific, hypsometric-terrain, and radar/satellite colour-map palettes #288

Description

@MAfarrag

Context

Cleopatra styles in-memory NumPy fields through named presets in src/cleopatra/styling/data/*.json,
resolved onto matplotlib colormaps at render time. This issue tracks the vendored colour-map palette
expansion delivered by PR #275: perceptually-uniform scientific maps, their hypsometric-terrain variants,
and radar/satellite meteorology colour tables — all addressable by name via DataStyle(style=...) /
cmap=, with no new hard dependency.

Note: the scientific, terrain, and radar palette files also landed independently on main (via
#246 / #287); PR #275 reconciles them and keeps the scrubbed, neutral-source form. This issue documents the
palette set as a whole so the delivered surface is tracked in one place.

Problem / Current Behaviour

Cleopatra shipped only a small built-in/ocean/NCL palette set. It lacked:

  • the perceptually-uniform scientific colour maps widely used for scientific figures,
  • their land/ocean hypsometric-terrain variants for elevation data,
  • standard radar/satellite meteorology colour tables (reflectivity, velocity, IR/water-vapour).

Affected locations

File Symbol Notes
src/cleopatra/styling/data/scientific_presets.json 39 palettes source="scientific", MIT
src/cleopatra/styling/data/terrain_presets.json 3 palettes hypsometric elevation ramps, MIT
src/cleopatra/styling/data/radar_presets.json 11 palettes source="nws", BSD-3-Clause
src/cleopatra/styling/colors.py _PRESET_ASSETS, resolve_colormap loads the JSON assets; namespaced (":") names
pyproject.toml [science-colors] extra optional cmap>=0.7.2, numpy-only aggregator; not a hard dep
tools/build_scientific_presets.py, tools/build_terrain_presets.py, tools/build_radar_presets.py maintainer-only build tools (local, untracked)

Motivation Example

from cleopatra.glyphs.gridded.array_glyph import ArrayGlyph
from cleopatra.styling.params import DataStyle

# perceptually-uniform scientific map
ArrayGlyph(field).plot(data_style=DataStyle(style="batlow"))
# hypsometric terrain ramp for elevation
ArrayGlyph(dem).plot(data_style=DataStyle(style="elevation_oleron"))
# radar reflectivity colour table
ArrayGlyph(dbz).plot(data_style=DataStyle(style="reflectivity"))

Delivered palettes

  • Scientific (39): acton, bam, bamO, bamako, batlow, batlowK, batlowW, berlin, bilbao, broc, brocO, buda,
    bukavu, cork, corkO, davos, devon, fes, glasgow, grayC, hawaii, imola, lajolla, lapaz, lipari, lisbon,
    managua, navia, nuuk, oleron, oslo, roma, romaO, tofino, tokyo, turku, vanimo, vik, vikO
  • Terrain (3): elevation_bukavu, elevation_fes, elevation_oleron
  • Radar/satellite (11): infrared, infrared_enhanced, precipitation_accumulation, radial_velocity,
    radial_velocity_hires, reflectivity, reflectivity_clear_air, reflectivity_expanded, spectrum_width,
    water_vapor, water_vapor_enhanced

Out of Scope

  • Weather/atmospheric composition presets (tracked separately).
  • Making cmap / any palette source a hard runtime dependency — palettes resolve from vendored JSON;
    the [science-colors] extra only enables namespaced (cmocean:, cmasher:) lookups.

Effort Estimate

Size: M
Rationale: vendoring + schema-fitting 53 palettes across three sources, loader wiring, an optional extra,
and gallery notebooks.

Definition of Done

  • scientific_presets.json, terrain_presets.json, radar_presets.json vendored under the v2 preset schema
  • _PRESET_ASSETS loads them; names resolve through resolve_colormap
  • optional [science-colors] extra enables namespaced colormap resolution (no hard dep)
  • gallery notebooks: scientific_colormaps_gallery, scientific_colormaps_examples, radar_satellite_gallery
  • no crameri / vendor-source names in code, docstrings, filenames, or data
  • all existing tests continue to pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions