Skip to content

fix: make the GUI helpers' colour scale constructible through the public API - #586

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/aplt-output-drift-remaining-repos
Aug 24, 2026
Merged

fix: make the GUI helpers' colour scale constructible through the public API#586
Jammy2211 merged 2 commits into
mainfrom
feature/aplt-output-drift-remaining-repos

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Closes part of #585.

Cmap is no longer exported by any public plot namespace — not
autoarray.plot, autogalaxy.plot, autolens.plot or autocti.plot. Two GUI
helpers in this repo still required one, so their colour scale could only be
supplied via a private-path import. A third gap surfaced while migrating the
downstream caller.

API Changes

Scribbler.__init__ — new arguments, backward compatible.

# before — needed an object no public namespace exports
al.Scribbler(image=..., cmap=aplt.Cmap(cmap="jet", norm="log", vmin=1e-3, vmax=3.0))

# after
al.Scribbler(image=..., cmap="jet", norm="log", vmin=1e-3, vmax=3.0)

norm, vmin and vmax are added and cmap now accepts a colormap name. A
legacy Cmap-style object exposing norm_from is still accepted and takes
precedence, so any caller holding an instance keeps working. Passing nothing is
unchanged.

plot_array — new optional mask= argument.

aplt.plot_array(array=data, mask=mask, positions=centres, use_log10=True, ...)

The wrapper delegates to autoarray.plot.plot_array but was silently dropping
that function's mask= parameter. Because the outline is otherwise auto-derived
from array.mask, a caller wanting to outline a different mask — the ordinary
preprocessing case of showing a candidate mask radius over unmasked data — had
no way to ask for it. Purely additive; omitting it preserves current behaviour.

Clicker.start() — bug fix, no signature change. It built
aplt.Cmap(...) on autoarray.plot unconditionally, so it raised for every
caller:

AttributeError: module 'autoarray.plot' has no attribute 'Cmap'

Removed: nothing. Deprecated: nothing.

Changes

  • util/plot_utils.py — adds norm_from(array, use_log10, vmin, vmax),
    mirroring the normalisation autoarray.plot.array.plot_array applies so code
    drawing its own axes scales colour identically; adds _mask_edge and the
    mask= passthrough.
  • gui/scribbler.py — flat colour arguments, legacy object path retained.
  • gui/clicker.py — uses the helper; its hardcoded scale is unchanged.
  • __init__.py — drops a duplicate Scribbler import present at both line 76
    and line 124.

Testing

test_autogalaxy/gui/ is new (the directory did not exist). 16 tests added
across two files: norm construction, the new signature, _mask_edge's contract,
and a regression guard asserting Cmap stays absent from the public namespaces.

The mask passthrough is verified by rendering, not just binding: on an
unmasked array auto_mask_edge returns None and no outline appears, while
passing mask= changes 2436 pixels of the output PNG.

Full suite green locally: 1129 passed on Python 3.12. CI covers 3.13.

Limitations, stated plainly

  • Scribbler.__init__ has no direct test. It calls matplotlib.use("TkAgg")
    and mng.window.wm_geometry, so it cannot run headless. The extracted
    norm_from helper carries the logic and is fully tested; the constructor's
    branching is covered only by signature binding.
  • Only Python 3.12 was run locally. Nothing here is version-sensitive, but
    3.13 is unverified until CI runs.

Follow-up, not fixed here

autoarray duplicates this same normalisation inline in plot/array.py and
plot/inversion.py. A shared helper there would be the real fix; this adds one
copy in autogalaxy serving both GUIs rather than a third inline copy.

Downstream

euclid_strong_lens_modeling_pipeline has a companion branch of the same name
that depends on both API changes. It must merge after this PR, per the
library-first gate.


Generated by Claude Code

Jonathan Nightingale and others added 2 commits August 24, 2026 21:59
`Cmap` is no longer exported by any public plot namespace (autoarray.plot,
autogalaxy.plot, autolens.plot, autocti.plot). Both GUI helpers still required
one, so their colour scale could only be supplied via a private-path import:

- `Clicker.start()` built `aplt.Cmap(...)` on `autoarray.plot` itself
  (clicker.py:31), so it raised `AttributeError: module 'autoarray.plot' has
  no attribute 'Cmap'` for every caller.
- `Scribbler.__init__` took a `Cmap`-shaped object as its `cmap=` argument,
  leaving callers no public way to colour the GUI.

Replace the object with flat arguments matching the `plot_array` convention:

- Add `norm_from(array, use_log10, vmin, vmax)` to `util/plot_utils.py`,
  mirroring the normalisation `autoarray.plot.array.plot_array` applies, so
  code drawing its own axes scales colour the same way the plot functions do.
- `Scribbler.__init__` gains `norm` / `vmin` / `vmax` and accepts a colormap
  name for `cmap`. A legacy `Cmap`-style object still works, so any caller
  holding an instance is not broken.
- `Clicker.start()` uses the helper directly; its hardcoded scale is unchanged.
- Drop the duplicate `Scribbler` import in `__init__.py` (it appeared at both
  line 76 and line 124), keeping the one grouped with `Clicker`.

Adds `test_autogalaxy/gui/`, which did not exist: nine tests over the norm
construction, the new signature, and a regression guard asserting `Cmap` stays
absent from the public namespaces. `Scribbler.__init__` itself is not covered
because it needs TkAgg and a display; the extracted helper carries the logic.

Full suite green on Python 3.12 (1122 passed); 3.13 is left to CI.

Note for a follow-up, not fixed here: autoarray duplicates this same
normalisation inline in `plot/array.py` and `plot/inversion.py`. A shared
helper there would be the real fix; this adds one copy in autogalaxy serving
both GUIs rather than a third inline copy.

Refs PyAutoGalaxy#585

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LN2Qsx6JjVKV45o17EKGtB
`plot_array` auto-derives its mask outline from `array.mask`, which yields
nothing for an unmasked array. The autogalaxy wrapper did not forward
autoarray's `mask=` parameter, so a caller wanting to outline a *different*
mask — the common preprocessing case of showing a candidate mask radius over
unmasked data — had no way to ask for it through the public API.

Add the `mask=` passthrough plus `_mask_edge`, which accepts a `Mask2D` (or
coordinates already in edge form) and mirrors `auto_mask_edge`'s contract of
returning None when there is no edge to draw.

Verified by rendering: on an unmasked array `auto_mask_edge` returns None and
the outline is absent, while passing `mask=` changes 2436 pixels of the output
PNG. Seven tests added in test_autogalaxy/plot/test_plot_array_mask.py.

Full suite green on Python 3.12 (1129 passed).

Refs PyAutoGalaxy#585

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LN2Qsx6JjVKV45o17EKGtB
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Aug 24, 2026 — with Claude
@Jammy2211
Jammy2211 merged commit d68a8f6 into main Aug 24, 2026
4 checks passed
@Jammy2211
Jammy2211 deleted the feature/aplt-output-drift-remaining-repos branch August 25, 2026 18:17
@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