Skip to content

feat: make the colormap config lever loud and documented (#509) - #510

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/cmap-magma-default
Aug 29, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/cmap-magma-default

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

The colormap lever (visualize/general.yaml -> colormap) already reached every 2D figure, but it was invisible and it failed quietly: _default_colormap() wrapped the config read in a bare except Exception, so a typo'd colormap name reverted to the bundled autoarray map with nothing said. This PR audits the lever end-to-end, makes malformed values loud, and documents both override routes.

  • Loud on malformed, quiet on absent. _default_colormap() now separates the two cases. No autonerves, or no colormap key on the config path (a bare install with no workspace) → quiet fallback to autoarray, as before. A value matplotlib cannot resolve → ValueError naming the key, the value, and the fix. The bare except Exception is replaced by ImportError / (KeyError, ConfigException).
  • Siblings tightened. _conf_imshow_origin() and _conf_output_format() get the same narrow excepts. imshow_origin additionally rejects anything but upper/lower; output_format is left to matplotlib's own savefig error, which already names the format and lists the supported ones.
  • Documented. autoarray/config/visualize/README.md gains a "Changing the colormap" section covering the global config key, the per-figure colormap= argument, and the figures that deliberately ignore both.

Reach audit (deliverable 1 of the issue)

Every 2D raster call in PyAutoArray resolves its colormap from the config, because all three drawing modules default colormap=None and then call _default_colormap():

Module Line Raster call
autoarray/plot/array.py 140-142 → 180, 187 imshow
autoarray/plot/grid.py 105-107 → 118-124 scatter
autoarray/plot/inversion.py 79-81 → 198, 214, 269 imshow / pcolormesh / tripcolor

Everything above them — autoarray/dataset/plot/, autoarray/fit/plot/, autoarray/inversion/plot/, PyAutoGalaxy's _resolve_colormap("default") (autogalaxy/util/plot_utils.py:97-102), PyAutoLens's tracer_plots.py / sensitivity_plots.py / imaging/plot/fit_imaging_plots.py — either threads colormap through or leaves it None, so the config value reaches the raster call on every path. No surface silently ignores the key.

Callers that omit colormap= (e.g. dataset/plot/imaging_plots.py:186-188) still honour the config — they just cannot be overridden per-figure from that level. plot_yx is a 1D line plot and takes no colormap.

Deliberate exceptions, now documented in the README rather than left silent:

  • autoarray/plot/array.py:208cmap="Greys" for the array_overlay. The overlay is drawn on top of the main array, so it must contrast with whatever colormap the main array uses.
  • autolens/weak/plot/weak_dataset_plots.pyviridis (ellipticities), twilight (position angles: cyclic data needs a cyclic map), magma (noise map).
  • autolens/weak/plot/fit_weak_plots.py:119RdBu_r (diverging, centred on the median residual).
  • autolens/weak/plot/convergence_plots.py:202magma.
  • autolens/cluster/plot/cluster_plots.py:49CLUSTER_CMAP = "gnuplot2".
  • autolens/potential_correction/*, autogalaxy/gui/clicker.pyjet in research and interactive-GUI-only code paths.

None of these are changed: the colormap carries meaning (cyclic, diverging, contrast) that a global preference should not silently override.

Per-figure override (deliverable 2)

The route already exists and is now documented and covered by a test: colormap= on any plot function.

aplt.plot_array(array=image, colormap="magma")
aplt.plot_inversion_reconstruction(pixel_values=values, mapper=mapper, colormap="viridis")

The "use the config value" default is spelled None in PyAutoArray and PyAutoLens, "default" in PyAutoGalaxy. No new code was needed.

API Changes

None — internal changes only. _default_colormap, _conf_imshow_origin and _conf_output_format are private; the colormap config key and every public colormap= argument keep their names and defaults.

One behaviour change is user-visible: a colormap (or imshow_origin) config value that was previously ignored now raises ValueError at plot time instead of silently reverting. Any config that was actually working is unaffected.

Test Plan

  • python -m pytest test_autoarray/plot -q — plot suite green
  • python -m pytest test_autoarray -q -n auto — full suite green
  • 11 new tests in test_autoarray/plot/test_utils.py: config value returned, absent key → quiet autoarray fallback + registration, unknown name → ValueError, non-string → ValueError, per-figure colormap= beats config, and one config edit moves both plot_array and plot_inversion_reconstruction
  • Control-tested: the three cmap-spy assertions were flipped to a sentinel and confirmed to fail, so they really observe the cmap handed to imshow
  • Acceptance demo rendered an imaging Array2D figure and a rectangular-mapper inversion reconstruction under colormap: magma — both visually magma, from the one config edit — and a malformed value raised the new error
Full API Changes (for automation & release notes)

Changed Behaviour

  • visualize/general.yaml -> colormap — a value that is not autoarray and not a registered matplotlib colormap now raises ValueError at plot time instead of silently falling back to autoarray.
  • visualize/general.yaml -> general -> imshow_origin — a value other than upper / lower now raises ValueError instead of silently falling back to upper.

Added

  • autoarray.plot.utils._validate_colormap(name) (private) — raises ValueError unless name is a registered matplotlib colormap.

Migration

  • None. Any config that produced the intended figure before produces the same figure now.

Generated by the PyAutoLabs agent workflow.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PXGHBFryzQZMFvAskHe9sQ

The `visualize/general.yaml -> colormap` key already reached every 2D figure,
but a typo'd or unknown value reverted silently to the bundled `autoarray`
colormap and the user never learned their setting was ignored.

- `_default_colormap()` now separates the two failure modes: an absent config
  (no autonerves, no `colormap` key) still falls back quietly to `autoarray`,
  while a value matplotlib cannot resolve raises a `ValueError` naming the
  config key, the offending value, and how to fix it. The bare `except
  Exception` is gone, replaced by `(KeyError, ConfigException)` / `ImportError`.
- `_conf_imshow_origin()` and `_conf_output_format()` get the same narrow
  excepts; `imshow_origin` additionally rejects anything but `upper`/`lower`.
- `config/visualize/README.md` gains a "Changing the colormap" section: the
  global config key, the per-figure `colormap=` argument, and the figures that
  deliberately fix their colormap (array_overlay `Greys`, the weak-lensing
  cyclic/diverging maps, the cluster and GUI maps).
- 11 new unit tests in `test_autoarray/plot/test_utils.py` cover the config
  value, the quiet fallback, the loud failure, the per-figure override, and
  that one config edit moves both an imaging figure and an inversion
  reconstruction.

No public API changes; the config key and every `colormap=` argument keep
their existing names and defaults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXGHBFryzQZMFvAskHe9sQ
@Jammy2211

Copy link
Copy Markdown
Collaborator Author

Workspace follow-up: PyAutoLabs/euclid_strong_lens_modeling_pipeline#42 (euclid_strong_lens_modeling_pipeline defaults to colormap: magma). Library-first merge gate: merge this PR before that one.

@Jammy2211
Jammy2211 merged commit 22191ec into main Aug 29, 2026
3 checks passed
@Jammy2211
Jammy2211 deleted the feature/cmap-magma-default branch August 29, 2026 01:52
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant