Skip to content

Commit 9792078

Browse files
committed
PR L5: Remove Visuals from PyAutoLens plotters; use standalone plot_array() with direct lines=/positions= kwargs
- abstract_plotters.py: Plotter._plot_array(array, auto_labels, lines=, positions=, visuals_2d=) uses autoarray.plot.plots.array.plot_array() directly; _to_lines()/_to_positions() helpers - tracer_util.py: add critical_curves_from(), caustics_from(), lines_of_planes_from() computing curves via LensCalc, returning plain numpy arrays; legacy visuals_2d_of_planes_list_from retained - tracer_plotters.py: cached _tangential/radial_critical_curves/caustics properties; figures_2d passes lines= directly; galaxies_plotter_from builds Visuals2D from cached curves - fit_imaging_plotters.py: lines_of_planes via tracer_util; _lines_for_plane() helper; figures_2d/_of_planes pass lines= not visuals_2d= - fit_interferometer_plotters.py: same pattern; dirty_model_image uses lines= - conftest.py: PlotPatch also patches matplotlib.figure.Figure.savefig - pyproject.toml: pin autogalaxy to claude/refactor-plotting-module-3ZdD8 https://claude.ai/code/session_01CzJBy8KvFXiNchoNdk5i9k
1 parent e6e265c commit 9792078

7 files changed

Lines changed: 855 additions & 495 deletions

File tree

autolens/imaging/plot/fit_imaging_plotters.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import copy
22
import numpy as np
3-
from typing import Optional
3+
from typing import Optional, List
44

55
from autoconf import conf
66

@@ -10,7 +10,7 @@
1010
from autoarray.plot.auto_labels import AutoLabels
1111
from autoarray.fit.plot.fit_imaging_plotters import FitImagingPlotterMeta
1212

13-
from autolens.plot.abstract_plotters import Plotter
13+
from autolens.plot.abstract_plotters import Plotter, _to_lines
1414
from autolens.imaging.fit_imaging import FitImaging
1515
from autolens.lens.plot.tracer_plotters import TracerPlotter
1616

@@ -63,19 +63,45 @@ def __init__(
6363
self.residuals_symmetric_cmap = residuals_symmetric_cmap
6464

6565
self._visuals_2d_of_planes_list = visuals_2d_of_planes_list
66+
self._lines_of_planes = None
6667

6768
@property
68-
def visuals_2d_of_planes_list(self):
69+
def _lensing_grid(self):
70+
return self.fit.grids.lp.mask.derive_grid.all_false
6971

70-
if self._visuals_2d_of_planes_list is None:
72+
@property
73+
def lines_of_planes(self) -> List[List]:
74+
"""Lists of line overlays (numpy arrays) per plane: critical curves for
75+
plane 0, caustics for higher planes."""
76+
if self._lines_of_planes is None:
77+
self._lines_of_planes = tracer_util.lines_of_planes_from(
78+
tracer=self.fit.tracer,
79+
grid=self._lensing_grid,
80+
)
81+
return self._lines_of_planes
7182

83+
@property
84+
def visuals_2d_of_planes_list(self):
85+
"""Legacy property: returns Visuals2D objects per plane for backward-
86+
compatible callers (e.g. InversionPlotter)."""
87+
if self._visuals_2d_of_planes_list is None:
7288
self._visuals_2d_of_planes_list = tracer_util.visuals_2d_of_planes_list_from(
7389
tracer=self.fit.tracer,
74-
grid=self.fit.grids.lp.mask.derive_grid.all_false,
90+
grid=self._lensing_grid,
7591
)
76-
7792
return self._visuals_2d_of_planes_list
7893

94+
def _lines_for_plane(
95+
self, plane_index: int, remove_critical_caustic: bool = False
96+
) -> Optional[List]:
97+
"""Return the line overlays for a given plane, or None if suppressed."""
98+
if remove_critical_caustic:
99+
return None
100+
try:
101+
return self.lines_of_planes[plane_index] or None
102+
except IndexError:
103+
return None
104+
79105
def visuals_2d_from(
80106
self, plane_index: Optional[int] = None, remove_critical_caustic: bool = False
81107
) -> aplt.Visuals2D:
@@ -255,11 +281,13 @@ def figures_2d_of_planes(
255281

256282
self._plot_array(
257283
array=self.fit.subtracted_images_of_planes_list[plane_index],
258-
visuals_2d=self.visuals_2d_from(
259-
plane_index=plane_index,
260-
remove_critical_caustic=remove_critical_caustic,
261-
),
262284
auto_labels=aplt.AutoLabels(title=title, filename=filename),
285+
lines=_to_lines(
286+
self._lines_for_plane(
287+
plane_index=plane_index,
288+
remove_critical_caustic=remove_critical_caustic,
289+
)
290+
),
263291
)
264292

265293
if model_image:
@@ -281,11 +309,13 @@ def figures_2d_of_planes(
281309

282310
self._plot_array(
283311
array=self.fit.model_images_of_planes_list[plane_index],
284-
visuals_2d=self.visuals_2d_from(
285-
plane_index=plane_index,
286-
remove_critical_caustic=remove_critical_caustic,
287-
),
288312
auto_labels=aplt.AutoLabels(title=title, filename=filename),
313+
lines=_to_lines(
314+
self._lines_for_plane(
315+
plane_index=plane_index,
316+
remove_critical_caustic=remove_critical_caustic,
317+
)
318+
),
289319
)
290320

291321
if plane_image:
@@ -881,7 +911,6 @@ def figures_2d(
881911

882912
self._plot_array(
883913
array=self.fit.data,
884-
visuals_2d=self.visuals_2d,
885914
auto_labels=AutoLabels(title="Data", filename=f"data{suffix}"),
886915
)
887916

@@ -892,7 +921,6 @@ def figures_2d(
892921

893922
self._plot_array(
894923
array=self.fit.noise_map,
895-
visuals_2d=self.visuals_2d,
896924
auto_labels=AutoLabels(
897925
title="Noise-Map", filename=f"noise_map{suffix}"
898926
),
@@ -902,7 +930,6 @@ def figures_2d(
902930

903931
self._plot_array(
904932
array=self.fit.signal_to_noise_map,
905-
visuals_2d=self.visuals_2d,
906933
auto_labels=AutoLabels(
907934
title="Signal-To-Noise Map",
908935
filename=f"signal_to_noise_map{suffix}",
@@ -916,10 +943,10 @@ def figures_2d(
916943

917944
self._plot_array(
918945
array=self.fit.model_data,
919-
visuals_2d=self.visuals_2d_from(plane_index=0),
920946
auto_labels=AutoLabels(
921947
title="Model Image", filename=f"model_image{suffix}"
922948
),
949+
lines=_to_lines(self._lines_for_plane(plane_index=0)),
923950
)
924951

925952
if use_source_vmax:
@@ -935,7 +962,6 @@ def figures_2d(
935962

936963
self._plot_array(
937964
array=self.fit.residual_map,
938-
visuals_2d=self.visuals_2d,
939965
auto_labels=AutoLabels(
940966
title="Residual Map", filename=f"residual_map{suffix}"
941967
),
@@ -945,7 +971,6 @@ def figures_2d(
945971

946972
self._plot_array(
947973
array=self.fit.normalized_residual_map,
948-
visuals_2d=self.visuals_2d,
949974
auto_labels=AutoLabels(
950975
title="Normalized Residual Map",
951976
filename=f"normalized_residual_map{suffix}",
@@ -958,7 +983,6 @@ def figures_2d(
958983

959984
self._plot_array(
960985
array=self.fit.chi_squared_map,
961-
visuals_2d=self.visuals_2d,
962986
auto_labels=AutoLabels(
963987
title="Chi-Squared Map",
964988
filename=f"chi_squared_map{suffix}",
@@ -969,7 +993,6 @@ def figures_2d(
969993

970994
self._plot_array(
971995
array=self.fit.residual_flux_fraction_map,
972-
visuals_2d=self.visuals_2d,
973996
auto_labels=AutoLabels(
974997
title="Residual Flux Fraction Map",
975998
filename=f"residual_flux_fraction_map{suffix}",

autolens/interferometer/plot/fit_interferometer_plotters.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional
1+
from typing import Optional, List
22

33
from autoconf import conf
44

@@ -11,7 +11,7 @@
1111
from autolens.interferometer.fit_interferometer import FitInterferometer
1212
from autolens.lens.tracer import Tracer
1313
from autolens.lens.plot.tracer_plotters import TracerPlotter
14-
from autolens.plot.abstract_plotters import Plotter
14+
from autolens.plot.abstract_plotters import Plotter, _to_lines
1515

1616
from autolens.lens import tracer_util
1717

@@ -79,20 +79,42 @@ def __init__(
7979
)
8080

8181
self._visuals_2d_of_planes_list = visuals_2d_of_planes_list
82+
self._lines_of_planes = None
8283

8384
@property
84-
def visuals_2d_of_planes_list(self):
85+
def _lensing_grid(self):
86+
return self.fit.grids.lp.mask.derive_grid.all_false
8587

88+
@property
89+
def lines_of_planes(self) -> List[List]:
90+
if self._lines_of_planes is None:
91+
self._lines_of_planes = tracer_util.lines_of_planes_from(
92+
tracer=self.fit.tracer,
93+
grid=self._lensing_grid,
94+
)
95+
return self._lines_of_planes
96+
97+
@property
98+
def visuals_2d_of_planes_list(self):
8699
if self._visuals_2d_of_planes_list is None:
87100
self._visuals_2d_of_planes_list = (
88101
tracer_util.visuals_2d_of_planes_list_from(
89102
tracer=self.fit.tracer,
90-
grid=self.fit.grids.lp.mask.derive_grid.all_false,
103+
grid=self._lensing_grid,
91104
)
92105
)
93-
94106
return self._visuals_2d_of_planes_list
95107

108+
def _lines_for_plane(
109+
self, plane_index: int, remove_critical_caustic: bool = False
110+
) -> Optional[List]:
111+
if remove_critical_caustic:
112+
return None
113+
try:
114+
return self.lines_of_planes[plane_index] or None
115+
except IndexError:
116+
return None
117+
96118
def visuals_2d_from(
97119
self, plane_index: Optional[int] = None, remove_critical_caustic: bool = False
98120
) -> aplt.Visuals2D:
@@ -289,10 +311,10 @@ def figures_2d(
289311
if dirty_model_image:
290312
self._plot_array(
291313
array=self.fit.dirty_model_image,
292-
visuals_2d=self.visuals_2d_of_planes_list[0],
293314
auto_labels=AutoLabels(
294315
title="Dirty Model Image", filename="dirty_model_image_2d"
295316
),
317+
lines=_to_lines(self._lines_for_plane(plane_index=0)),
296318
)
297319

298320
def figures_2d_of_planes(

0 commit comments

Comments
 (0)