Repository navigation
Description
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
- Library first (PyAutoLens): add two missing exports to
autolens/plot/__init__.py—subplot_interferometer_datasetandsubplot_fit_interferometer_combined. This is the mirror of PyAutoGalaxy#538, which closed the same asymmetry in the other direction. Merges before the workspace leg. - autolens_workspace: fill five
plot.pyfiles with the dataset/fit-level functions they omit, plus afits_*output section. - autogalaxy_workspace: same for two
plot.pyfiles. - Deliberately excluded: the
*_x1_planepair (unreachable —subplot_fitself-dispatches to them for single-plane tracers),subplot_ellipse_errors(needs a posterior), results/search plots (belong inguides/). - 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.pyscripts - autogalaxy_workspace — two
plot.pyscripts
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_datasetto the existingfrom autoarray.dataset.plot.interferometer_plots import (...)block.autogalaxy.plotexports it from that same module;autolens.plotimports onlysubplot_interferometer_dirty_imagesandfits_interferometerand skips it. Consequence:autolens_workspace/scripts/interferometer/plot.pyhas no dataset subplot while its autogalaxy counterpart does — the function is unreachable, so this is not a workspace gap. - Add
subplot_fit_interferometer_combinedto thefrom autolens.interferometer.plot.fit_interferometer_plots import (...)block. It is autolens's own function, unexported, while the imaging equivalentsubplot_fit_combinedis 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_listis deliberate — AL usessubplot_fit_combinedinstead.) - 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 insideautolens.plot, shadowing autolens's own versions that take lensing-specificimage_plane_lines/source_plane_linesargs — rebinding an exported name is a behaviour change and belongs in its own prompt.
2. autolens_workspace
scripts/imaging/plot.py— addsubplot_fit_imaging_log10;subplot_fit_imaging_of_planes(keep the existingmodel_images_of_planes_listsection, which demos attribute access, and add the subplot the Visualizer prose already names);subplot_fit_imaging_tracer; afits_imagingoutput section; one prose line notingsubplot_fitauto-switches to a 2×3 layout for single-plane tracers.scripts/interferometer/plot.py— addsubplot_interferometer_dataset(gated on the library merge),subplot_fit_interferometer_real_space,subplot_fit_interferometer_tracer, fit-levelsubplot_fit_dirty_images,fits_interferometer.scripts/weak/plot.py— addplot_data_vs_model,plot_residuals,plot_chi_squared_map,plot_convergence_map.scripts/cluster/plot.py— addplot_image_group_zooms,plot_critical_curves,plot_caustics.scripts/point_source/plot.py— addsubplot_point_dataset.
3. autogalaxy_workspace
scripts/imaging/plot.py— addsubplot_fit_imaging_of_galaxy,fits_imaging.scripts/interferometer/plot.py— addsubplot_fit_real_space, fit-levelsubplot_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_fitdispatches to them itself (fit_imaging_plots.py:214,:346,:512) whenlen(fit.tracer.planes) == 1. On the two-plane example fits inplot.pythey are unreachable by design; demoing them would teach a wrong idiom. Cover with one prose line.subplot_ellipse_errors— needsfit_pdf_list: List[List[FitEllipse]], one inner list per posterior sample. A standaloneplot.pyhas no search. File as its own follow-up prompt.- Results/search plots (
subplot_parameters,log_likelihood_vs_iteration,output_figure,corner_anesthetic) — belong toguides/plot/searches.pyandguides/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-flightgit diff --statbefore any commit (ship_workspacehas 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 exportsautolens_workspace/scripts/{imaging,interferometer,weak,cluster,point_source}/plot.pyautogalaxy_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_dataset—autogalaxy.plotexports it from
autoarray.dataset.plot.interferometer_plots;autolens.plotimports only
subplot_interferometer_dirty_imagesandfits_interferometerfrom 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 equivalentsubplot_fit_combinedis 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_fitdispatches to them itself
(fit_imaging_plots.py:214,:346,:512) when
len(fit.tracer.planes) == 1. On the two-plane example fits inplot.pythey
are unreachable by design; demoing them would teach a wrong idiom. Cover with
one prose line notingsubplot_fitauto-switches layout for single-plane
tracers.subplot_ellipse_errors— needsfit_pdf_list: List[List[FitEllipse]],
one inner list per posterior sample. A standaloneplot.pyhas 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 toguides/plot/searches.py
andguides/results/, not the per-datasetplot.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.pyscripts. - @autogalaxy_workspace — two
plot.pyscripts.
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 eachplot.py. - Skip
subplot_ellipse_errors; file a follow-up.
Activity
Jammy2211 commentedon Jul 30, 2026
Library PR Created
PR: #668 (
pending-release)Commit:
c3c00874confeature/plot-coverage-gapsAPI changes
Added-only; nothing removed, renamed, or resignatured.
aplt.subplot_interferometer_dataset— re-export ofautoarray.dataset.plot.interferometer_plots.subplot_interferometer_dataset, already exported byautogalaxy.plotaplt.subplot_fit_interferometer_combined— re-export of autolens's ownautolens.interferometer.plot.fit_interferometer_plots.subplot_fit_interferometer_combinedapltexport count 61 → 63.set(dir(autogalaxy.plot)) - set(dir(autolens.plot))now reduces to just{subplot_fit_imaging_list}(deliberate — AL usessubplot_fit_combined).Verification
autolensrather than the installed stackgit diff --stat= 2 files, 5 insertions, 1 deletionHeart at ship time:
verdict: stale, score 75, withred_reasons: []andyellow_reasons: []— both entries arestale_reasons(test run status unknown (no report.json);release validation stale: source moved since rehearsal). Out-of-date evidence rather than a failure; acknowledged by the human before ship.Workspace impact
Option (i) new demos. Grep across all workspace
scripts/trees found the two new symbols used only by autogalaxy's own pre-existing calls (autogalaxy_workspace/scripts/interferometer/{plot,fit}.py) — which are unaffected, since AG already exportedsubplot_interferometer_dataset. Zero autolens usage, confirming the symbol was genuinely unreachable fromautolens.plot. No migration needed.Next:
/start_workspacefor the 7plot.pyfiles —autolens_workspace(imaging, interferometer, weak, cluster, point_source) andautogalaxy_workspace(imaging, interferometer). The AL interferometer dataset subplot depends on this PR's first export; the workspace scripts will be validated against the branch build via the shared task worktree, but the workspace PR stays behind the library-first merge gate.Jammy2211 commentedon Jul 30, 2026
Workspace PRs Created — all three legs open
c3c00874c72ff4e6fc9746d0All three carry
pending-release.Merge order
PyAutoLens#668 must merge first.
autolens_workspace/scripts/interferometer/plot.pynow callsaplt.subplot_interferometer_dataset, which only exists after that PR. autogalaxy_workspace#191 has no such dependency and is safe to merge independently.Nothing has been merged — merge stays a human decision.
What shipped
7
plot.pyscripts, +302 lines of examples (plus regenerated notebooks).subplot_fit_imaging_of_planes,subplot_fit_imaging_log10,subplot_fit_imaging_tracer,fits_imagingsubplot_interferometer_dataset, fit-levelsubplot_fit_dirty_images,subplot_fit_interferometer_real_space,subplot_fit_interferometer_tracer,fits_interferometerplot_convergence_map,plot_data_vs_model,plot_residuals,plot_chi_squared_mapplot_image_group_zooms,plot_critical_curves,plot_causticssubplot_point_datasetsubplot_fit_imaging_of_galaxy,use_log10variant,fits_imagingsubplot_fit_dirty_images,subplot_fit_real_space,fits_interferometerplot.pycoverage: 18 → 36 of 63 exported symbols (autolens_workspace), 11 → 14 of 28 (autogalaxy_workspace).Validation
*_x1_planepair confirmed called nowhere.fits_*sections write tooutput/plot/…(gitignored, verified withgit check-ignore); the written FITS was opened and confirmed to holdMASK,DATA,PSF,NOISE_MAP.One honest gap
subplot_fit_interferometer_combinedwas exported in #668 for API symmetry with imaging'ssubplot_fit_combined, but is not demonstrated anywhere. It takes afit_list, so its home is a multi-dataset interferometer example rather than the single-fitinterferometer/plot.py— passing[fit, fit]would teach a wrong idiom. Recorded as a follow-up below.Follow-ups filed as Mind drafts (not issues)
subplot_fit_interferometer_combinedin a multi-dataset interferometer example.subplot_ellipse_errors— needs a posteriorfit_pdf_list, so it needs a real ellipse model-fit.docs/api/plot.rstomits several already-exported symbols (subplot_imaging_dataset,subplot_imaging_dataset_list,fits_imaging,fits_interferometer,subplot_fit_interferometer_tracer,subplot_interferometer_dirty_images).aplt.subplot_fit_dirty_imagesandaplt.subplot_fit_real_spaceresolve to the autogalaxy implementations insideautolens.plot, shadowing autolens's own versions which accept lensing-specificimage_plane_lines/source_plane_lines. Rebinding an exported name is a behaviour change, so it was kept out of feat: export subplot_interferometer_dataset + subplot_fit_interferometer_combined #668.Jammy2211 commentedon Jul 30, 2026
Shipped — all three PRs merged
45ac1dbaf6ca53f89c5b558f5c2Merged in the required order: the library export first, then the workspaces.
Post-merge integration check
Verified against the canonical merged mains (not the task worktree — asserted
autolens.__file__is outsidePyAutoLabs-wt), which is what catches a merge-order mistake that per-PR CI cannot:aplt.subplot_interferometer_datasetandaplt.subplot_fit_interferometer_combinedboth resolve on mergedPyAutoLensmain.autolens_workspace/scripts/interferometer/plot.py— the merge-order-critical script — runs to completion (exit 0) on merged mains.autogalaxy_workspace/scripts/interferometer/plot.pyruns to completion (exit 0).fits_*sections wrote only into gitignoredoutput/plot/.CI at merge: PyAutoLens 5/5 green; autogalaxy_workspace 10/10 green; autolens_workspace 10/10 green (both runs × both matrix legs each — the smoke matrix produces two runs per head, and all legs were checked).
Final state
plot.pycoverage: 18 → 36 of 63 exported symbols (autolens_workspace), 11 → 14 of 28 (autogalaxy_workspace). 22/22 planned gaps closed, verified by re-running the coverage matrix against the edited files rather than trusting the edits.Note the workspace mains now call
aplt.subplot_interferometer_dataset, which is unreleased — both workspace PRs carriedpending-release, so this is expected until the next release publishes.Follow-ups
Recorded as Mind drafts in
draft/docs/workspaces/plot_coverage_followups.md, deliberately not bulk-issued:subplot_fit_interferometer_combined— exported here for API symmetry but demonstrated nowhere; needs a multi-dataset interferometer context.subplot_ellipse_errors— needs a real posteriorfit_pdf_list.docs/api/plot.rstomits 6 already-exported symbols.autolens.plotshadows its ownsubplot_fit_dirty_imageswith autogalaxy's — the autolens version takingimage_plane_linesis reachable under no exported name at all.Leaving this issue open for #4 in particular, which is a live (if minor) API defect. Close whenever you're happy.
Jammy2211 commentedon Jul 30, 2026
Follow-up 4 resolved — PyAutoLens#670 merged (
339867e2c)The shadowing defect is fixed additively:
subplot_fit_interferometer_dirty_imagesnow exports autolens's own function, so it is reachable for the first time.subplot_fit_dirty_imagesis deliberately left bound to the autogalaxy version. The two signatures diverge (residuals_symmetric_cmapon the AG side,image_plane_lines/image_plane_line_colorson the AL side), so rebinding it would be a behaviour change rather than an additive export. This matches the convention already in the file —subplot_fit_real_space(AG) has long coexisted withsubplot_fit_interferometer_real_space(AL);subplot_fit_dirty_imageshad simply never been given its counterpart.Worth recording: the AL version is not a duplicate
With
image_plane_lines=Noneit auto-derives the tracer's critical curves from the fit via_compute_critical_curve_linesand overlays them on the dirty model image — lensing information the autogalaxy version cannot produce. Verified functionally on a realFitInterferometer(1 curve derived), not just signature-checked.Verification
autolens.…, old name →autogalaxy.…(unchanged).One sub-item deliberately deferred
autolens_workspacestill calls the autogalaxy-boundaplt.subplot_fit_dirty_imagesat 11 sites —scripts/interferometer/{fit,modeling,plot}.py, fourscripts/interferometer/features/*/fit.py, andscripts/multi/features/imaging_and_interferometer/modeling.py. All passfit=fitonly, so all 11 could switch to the new name and gain critical-curve overlays for free.Not done here: that is a visual change across 11 lens examples and deserves its own review pass rather than riding along with an export fix. Recorded in
draft/docs/workspaces/plot_coverage_followups.md.Follow-ups 1-3 (demo
subplot_fit_interferometer_combined, demosubplot_ellipse_errors,docs/api/plot.rstomissions) remain open in that same file.Jammy2211 commentedon Jul 30, 2026
Closing — all four PRs merged
45ac1dbafplot.pyfiles6ca53f89cplot.pyfiles5b558f5c2subplot_fit_interferometer_dirty_images(follow-up 4)339867e2cplot.pycoverage: 18 → 36 of 63 exported symbols (autolens_workspace), 11 → 14 of 28 (autogalaxy_workspace). 22/22 planned gaps closed, verified by re-running the coverage matrix against the edited files.Remaining work is tracked as Mind drafts in
draft/docs/workspaces/plot_coverage_followups.md, deliberately not bulk-issued:subplot_fit_interferometer_combined— exported, demonstrated nowhere (needs a multi-dataset interferometer context).subplot_ellipse_errors— needs a real posteriorfit_pdf_list.docs/api/plot.rstomits 6 already-exported symbols and has no dataset heading.autolens_workspacecall sites fromsubplot_fit_dirty_imagestosubplot_fit_interferometer_dirty_images— a visual change across 11 lens examples, wants its own review pass.Note the workspace mains call
aplt.subplot_interferometer_dataset, which is unreleased; both workspace PRs carriedpending-release, so this resolves at the next release.