Skip to content

docs: fill plot.py coverage gaps vs source *_plots.py (+2 missing autolens exports) #667

Description

@Jammy2211

Overview

Direct follow-on to plot-guides-restructure. That task created the per-dataset plot.py family across both workspaces and closed the AG→AL export asymmetry via PyAutoGalaxy#538 — but it restructured, it did not enumerate. It never audited whether each plot.py demonstrates the full set of plotting functions its dataset/fit type actually has.

An audit of every public function in the source *_plots.py modules against every aplt.* call in both workspaces shows substantial gaps. Most visibly, autolens_workspace/scripts/imaging/plot.py calls subplot_fit_imaging and nothing else: subplot_fit_imaging_log10, subplot_fit_imaging_of_planes and subplot_fit_imaging_tracer appear nowhere in the entire workspace. That file's own __Visualizer__ section even names subplot_of_planes in prose while never demonstrating it, and hand-rolls a fit.model_images_of_planes_list loop in its place.

The audit also surfaced two genuine library gaps: autolens/plot/__init__.py is missing two exports, which is why the AL interferometer example has no dataset subplot while its AG counterpart does. This task fixes those first, then fills the workspace coverage.

Plan

  1. Library first (PyAutoLens): add two missing exports to autolens/plot/__init__.pysubplot_interferometer_dataset and subplot_fit_interferometer_combined. This is the mirror of PyAutoGalaxy#538, which closed the same asymmetry in the other direction. Merges before the workspace leg.
  2. autolens_workspace: fill five plot.py files with the dataset/fit-level functions they omit, plus a fits_* output section.
  3. autogalaxy_workspace: same for two plot.py files.
  4. Deliberately excluded: the *_x1_plane pair (unreachable — subplot_fit self-dispatches to them for single-plane tracers), subplot_ellipse_errors (needs a posterior), results/search plots (belong in guides/).
  5. Validate by sequential test-mode runs with visualization on, then re-run the coverage matrix on the output to prove the gaps actually closed.
Detailed implementation plan

Work Classification

Both (library → workspace). Worktree root: ~/Code/PyAutoLabs-wt/plot-coverage-gaps/

Affected Repositories

  • PyAutoLens (primary) — two additive exports; merges first
  • autolens_workspace — five plot.py scripts
  • autogalaxy_workspace — two plot.py scripts

Branch Survey

Repository Current Branch Dirty?
./PyAutoLens main clean
./autolens_workspace main clean
./autogalaxy_workspace main clean

Suggested branch: feature/plot-coverage-gaps

worktree_check_conflict flagged PyAutoLens as claimed by python-312-floor — hand-verified stale: git -C PyAutoLens worktree list shows a single canonical worktree on main, main has moved 3 commits past the claimed b40fb0ba, and python-312-floor records next-phase: none — all phases complete. Those - Repo lines are a completion record, not a live claim.

Evidence method

Enumerate every public function in the source *_plots.py modules, resolve what aplt actually exports by introspecting the installed stack (not by reading __init__.py), then grep every aplt.* call across both workspaces, bucketed as demoed-in-a-plot.py / used-elsewhere / never-used.

Implementation Steps

1. PyAutoLens — autolens/plot/__init__.py

  • Add subplot_interferometer_dataset to the existing from autoarray.dataset.plot.interferometer_plots import (...) block. autogalaxy.plot exports it from that same module; autolens.plot imports only subplot_interferometer_dirty_images and fits_interferometer and skips it. Consequence: autolens_workspace/scripts/interferometer/plot.py has no dataset subplot while its autogalaxy counterpart does — the function is unreachable, so this is not a workspace gap.
  • Add subplot_fit_interferometer_combined to the from autolens.interferometer.plot.fit_interferometer_plots import (...) block. It is autolens's own function, unexported, while the imaging equivalent subplot_fit_combined is exported.
  • Verified by import, not by reading source: set(dir(autogalaxy.plot)) - set(dir(autolens.plot)) == {subplot_fit_imaging_list, subplot_interferometer_dataset}. (subplot_fit_imaging_list is deliberate — AL uses subplot_fit_combined instead.)
  • Both changes are additive; no behaviour change. Explicitly not touching subplot_fit_dirty_images / subplot_fit_real_space, which currently resolve to the autogalaxy implementations inside autolens.plot, shadowing autolens's own versions that take lensing-specific image_plane_lines / source_plane_lines args — rebinding an exported name is a behaviour change and belongs in its own prompt.

2. autolens_workspace

  • scripts/imaging/plot.py — add subplot_fit_imaging_log10; subplot_fit_imaging_of_planes (keep the existing model_images_of_planes_list section, which demos attribute access, and add the subplot the Visualizer prose already names); subplot_fit_imaging_tracer; a fits_imaging output section; one prose line noting subplot_fit auto-switches to a 2×3 layout for single-plane tracers.
  • scripts/interferometer/plot.py — add subplot_interferometer_dataset (gated on the library merge), subplot_fit_interferometer_real_space, subplot_fit_interferometer_tracer, fit-level subplot_fit_dirty_images, fits_interferometer.
  • scripts/weak/plot.py — add plot_data_vs_model, plot_residuals, plot_chi_squared_map, plot_convergence_map.
  • scripts/cluster/plot.py — add plot_image_group_zooms, plot_critical_curves, plot_caustics.
  • scripts/point_source/plot.py — add subplot_point_dataset.

3. autogalaxy_workspace

  • scripts/imaging/plot.py — add subplot_fit_imaging_of_galaxy, fits_imaging.
  • scripts/interferometer/plot.py — add subplot_fit_real_space, fit-level subplot_fit_dirty_images, fits_interferometer.

Note the two distinct dirty-image functions: dataset-level subplot_interferometer_dirty_images (already demoed) vs fit-level subplot_fit_dirty_images (missing from both workspaces' plot.py).

Excluded, with reasons

  • subplot_fit_imaging_x1_plane / subplot_fit_imaging_log10_x1_plane — do not add as calls. subplot_fit dispatches to them itself (fit_imaging_plots.py:214, :346, :512) when len(fit.tracer.planes) == 1. On the two-plane example fits in plot.py they are unreachable by design; demoing them would teach a wrong idiom. Cover with one prose line.
  • subplot_ellipse_errors — needs fit_pdf_list: List[List[FitEllipse]], one inner list per posterior sample. A standalone plot.py has no search. File as its own follow-up prompt.
  • Results/search plots (subplot_parameters, log_likelihood_vs_iteration, output_figure, corner_anesthetic) — belong to guides/plot/searches.py and guides/results/. Separate audit.
  • Tracer/galaxy/profile subplots stay in guides/ (guides/tracer.py, guides/galaxies.py, guides/plot/start_here.py) where already covered — do not duplicate.

Risks / trade-offs

  • The fits_* sections write files. They must target an ignored output path or these scripts will leak binaries into the repo — pre-flight git diff --stat before any commit (ship_workspace has leaked binary outputs before).
  • Every added call must be executed, not just written. Run sequentially: parallel workspace runs fake failures through shared state.
  • Library/workspace merge order: the interferometer dataset subplot cannot land in the workspace until the PyAutoLens export merges.

Testing approach

Sequential test-mode runs with visualization on for every touched script (the restructure task's bar was 13/13 AL, 10/10 AG). Then re-run the aplt coverage matrix against the edited files to prove the gaps actually closed, rather than trusting the edit.

Key Files

  • PyAutoLens/autolens/plot/__init__.py — the two additive exports
  • autolens_workspace/scripts/{imaging,interferometer,weak,cluster,point_source}/plot.py
  • autogalaxy_workspace/scripts/{imaging,interferometer}/plot.py

Process notes

Brain override. The Feature Agent returned too-large (score 15) and a 4-phase split (design / core_api / workspace_examples / docs). Overridden to one combined library→workspace task — it scored 3 repos, not the work; there is no design left (the audit is the design) and no core API beyond two import lines. Precedent: vacuous-jax-assertions (large/8 → small), multiband-pyloop-batching.

Heart at intake. STALE 75 — test run status unknown (no report.json), release validation stale: source moved since rehearsal (PyAutoFit, PyAutoArray, PyAutoGalaxy, PyAutoLens). Both unrelated to this docs change.

Original Prompt

Click to expand starting prompt

plot.py function coverage gaps vs the source *_plots.py modules

Direct follow-on to plot-guides-restructure (complete/2026/07). That task
created the per-dataset plot.py family and closed the AG→AL export asymmetry
via PyAutoGalaxy#538. It did not audit whether each plot.py demonstrates
the full set of plotting functions its dataset/fit type actually has — it
restructured, it did not enumerate. This task closes that.

Two legs: a small library export fix in PyAutoLens (the mirror of #538,
which went the other direction), then the workspace coverage fill.

Evidence

Method: enumerate every public function in the source *_plots.py modules,
resolve what aplt actually exports by introspecting the installed stack
(not by reading __init__.py), then grep every aplt.* call across both
workspaces, bucketed as demoed-in-a-plot.py / used-elsewhere / never-used.

Confirmed: autolens_workspace/scripts/imaging/plot.py calls
subplot_fit_imaging only. subplot_fit_imaging_log10,
subplot_fit_imaging_of_planes and subplot_fit_imaging_tracer appear
nowhere in the entire workspace. The file's own __Visualizer__ section
even names subplot_of_planes in prose while never demonstrating it, and
hand-rolls a fit.model_images_of_planes_list loop in its place.

Library leg — PyAutoLens

autolens/plot/__init__.py is missing two exports:

  • subplot_interferometer_datasetautogalaxy.plot exports it from
    autoarray.dataset.plot.interferometer_plots; autolens.plot imports only
    subplot_interferometer_dirty_images and fits_interferometer from that same
    module and skips it. Consequence: autolens_workspace/scripts/interferometer/plot.py
    has no dataset subplot while its autogalaxy counterpart does — the
    function is unreachable, so this is not a workspace gap.
  • subplot_fit_interferometer_combined — autolens's own function in
    autolens/interferometer/plot/fit_interferometer_plots.py, unexported, while
    the imaging equivalent subplot_fit_combined is exported.

Verified by import, not by reading source:
set(dir(autogalaxy.plot)) - set(dir(autolens.plot)) =
{subplot_fit_imaging_list, subplot_interferometer_dataset}. (subplot_fit_imaging_list
is deliberate — AL uses subplot_fit_combined instead.)

Also noted, not in scope: aplt.subplot_fit_dirty_images and
aplt.subplot_fit_real_space resolve to the autogalaxy implementations
inside autolens.plot, shadowing autolens's own versions which take
lensing-specific image_plane_lines / source_plane_lines args. Worth a
separate prompt — changing what an existing exported name resolves to is a
behaviour change, not an additive export.

Workspace leg

Each plot.py demonstrates the dataset- and fit-level functions for its own
data type, plus a fits_* output section. Tracer/galaxy/profile subplots stay
in guides/ (guides/tracer.py, guides/galaxies.py,
guides/plot/start_here.py) where they are already covered — do not duplicate.

autolens_workspace

File Add
scripts/imaging/plot.py subplot_fit_imaging_log10, subplot_fit_imaging_of_planes, subplot_fit_imaging_tracer, fits_imaging
scripts/interferometer/plot.py subplot_interferometer_dataset (needs the library leg), subplot_fit_interferometer_real_space, subplot_fit_interferometer_tracer, fit-level subplot_fit_dirty_images, fits_interferometer
scripts/weak/plot.py plot_data_vs_model, plot_residuals, plot_chi_squared_map, plot_convergence_map
scripts/cluster/plot.py plot_image_group_zooms, plot_critical_curves, plot_caustics
scripts/point_source/plot.py subplot_point_dataset

autogalaxy_workspace

File Add
scripts/imaging/plot.py subplot_fit_imaging_of_galaxy, fits_imaging
scripts/interferometer/plot.py subplot_fit_real_space, fit-level subplot_fit_dirty_images, fits_interferometer

Note the two distinct dirty-image functions: dataset-level
subplot_interferometer_dirty_images (already demoed) vs fit-level
subplot_fit_dirty_images (missing in both workspaces' plot.py).

Explicitly excluded

  • subplot_fit_imaging_x1_plane / subplot_fit_imaging_log10_x1_plane
    do not add as calls. subplot_fit dispatches to them itself
    (fit_imaging_plots.py:214, :346, :512) when
    len(fit.tracer.planes) == 1. On the two-plane example fits in plot.py they
    are unreachable by design; demoing them would teach a wrong idiom. Cover with
    one prose line noting subplot_fit auto-switches layout for single-plane
    tracers.
  • subplot_ellipse_errors — needs fit_pdf_list: List[List[FitEllipse]],
    one inner list per posterior sample. A standalone plot.py has no search, so
    this needs a real model-fit. File as its own follow-up prompt.
  • Results/search plots (subplot_parameters, log_likelihood_vs_iteration,
    output_figure, corner_anesthetic) — belong to guides/plot/searches.py
    and guides/results/, not the per-dataset plot.py. Several are used
    nowhere; a separate audit.

Validation

Sequential test-mode runs with visualization on for every touched script (the
restructure task's own bar: 13/13 AL, 10/10 AG). Parallel runs fake failures
through shared state — baseline sequentially.

Re-run the coverage matrix on the output to prove the gaps actually closed,
rather than trusting the edit.

Repos

  • @PyAutoLens — autolens/plot/__init__.py, two additive exports. Merges first.
  • @autolens_workspace — five plot.py scripts.
  • @autogalaxy_workspace — two plot.py scripts.

Original request (verbatim)

we just finished a task refactoring all the plot.py files in the workspce, but I
think we are missing some plot fuhnctions. For example, imaging/plot.py has
subplot_fit but not subplot_fit_log10, subplot_of_planes, etc. Do a better
comparison of the *_plots.py files in the source code and the plot.py in the
workspace and fill in the gaps across autolens and autogalaxy

Scope decisions taken by the human at intake:

  • Library + workspace (fix the two missing PyAutoLens exports, library merges first).
  • Also add fits_* output sections to each plot.py.
  • Skip subplot_ellipse_errors; file a follow-up.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions