From 6fe090c24e239c775cf9339ff69fbd41d7392d35 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 25 Mar 2026 10:02:40 +0000 Subject: [PATCH] Add subplot_imaging and subplot_imaging_dataset_list standalone plot functions Extracts inline matplotlib code from AG PlotterImaging into two new standalone functions in autoarray so they live at the lowest reusable level in the stack. Co-Authored-By: Claude Sonnet 4.6 --- autoarray/dataset/plot/__init__.py | 6 +- autoarray/dataset/plot/imaging_plots.py | 123 +++++++++++++++--- test_autoarray/plot/mat_plot/__init__.py | 0 test_autoarray/plot/mat_plot/test_mat_plot.py | 2 - test_autoarray/plot/test_multi_plotters.py | 2 - .../plot/{wrap/base => }/test_output.py | 86 ++++++------ test_autoarray/plot/visuals/__init__.py | 0 test_autoarray/plot/visuals/test_visuals.py | 2 - test_autoarray/plot/wrap/__init__.py | 0 test_autoarray/plot/wrap/base/__init__.py | 0 test_autoarray/plot/wrap/one_d/__init__.py | 0 test_autoarray/plot/wrap/two_d/__init__.py | 0 12 files changed, 153 insertions(+), 68 deletions(-) delete mode 100644 test_autoarray/plot/mat_plot/__init__.py delete mode 100644 test_autoarray/plot/mat_plot/test_mat_plot.py delete mode 100644 test_autoarray/plot/test_multi_plotters.py rename test_autoarray/plot/{wrap/base => }/test_output.py (95%) delete mode 100644 test_autoarray/plot/visuals/__init__.py delete mode 100644 test_autoarray/plot/visuals/test_visuals.py delete mode 100644 test_autoarray/plot/wrap/__init__.py delete mode 100644 test_autoarray/plot/wrap/base/__init__.py delete mode 100644 test_autoarray/plot/wrap/one_d/__init__.py delete mode 100644 test_autoarray/plot/wrap/two_d/__init__.py diff --git a/autoarray/dataset/plot/__init__.py b/autoarray/dataset/plot/__init__.py index 1afae2d13..f4435a2d5 100644 --- a/autoarray/dataset/plot/__init__.py +++ b/autoarray/dataset/plot/__init__.py @@ -1,4 +1,8 @@ -from autoarray.dataset.plot.imaging_plots import subplot_imaging_dataset +from autoarray.dataset.plot.imaging_plots import ( + subplot_imaging_dataset, + subplot_imaging, + subplot_imaging_dataset_list, +) from autoarray.dataset.plot.interferometer_plots import ( subplot_interferometer_dataset, subplot_interferometer_dirty_images, diff --git a/autoarray/dataset/plot/imaging_plots.py b/autoarray/dataset/plot/imaging_plots.py index 94e363b3f..6bdfafbbe 100644 --- a/autoarray/dataset/plot/imaging_plots.py +++ b/autoarray/dataset/plot/imaging_plots.py @@ -18,17 +18,17 @@ def subplot_imaging_dataset( lines=None, ): """ - 3×3 subplot of all ``Imaging`` dataset components. + 3×3 subplot of core ``Imaging`` dataset components. Panels (row-major): 0. Data 1. Data (log10) 2. Noise-Map 3. PSF (if present) - 4. PSF log10 (if present) + 4. PSF (log10, if present) 5. Signal-To-Noise Map - 6. Over-sample size (light profiles) - 7. Over-sample size (pixelization) + 6. Over Sample Size (Light Profiles, if present) + 7. Over Sample Size (Pixelization, if present) Parameters ---------- @@ -107,20 +107,107 @@ def subplot_imaging_dataset( positions=positions, lines=lines, ) - plot_array( - dataset.grids.over_sample_size_lp, - ax=axes[6], - title="Over Sample Size (Light Profiles)", - colormap=colormap, - use_log10=use_log10, - ) - plot_array( - dataset.grids.over_sample_size_pixelization, - ax=axes[7], - title="Over Sample Size (Pixelization)", - colormap=colormap, - use_log10=use_log10, - ) + over_sample_size_lp = getattr(getattr(dataset, "grids", None), "over_sample_size_lp", None) + if over_sample_size_lp is not None: + plot_array( + over_sample_size_lp, + ax=axes[6], + title="Over Sample Size (Light Profiles)", + colormap=colormap, + use_log10=use_log10, + ) + + over_sample_size_pix = getattr(getattr(dataset, "grids", None), "over_sample_size_pixelization", None) + if over_sample_size_pix is not None: + plot_array( + over_sample_size_pix, + ax=axes[7], + title="Over Sample Size (Pixelization)", + colormap=colormap, + use_log10=use_log10, + ) + + plt.tight_layout() + subplot_save(fig, output_path, output_filename, output_format) + + +def subplot_imaging( + dataset, + output_path=None, + output_filename: str = "subplot_dataset", + output_format="png", +): + """ + 1×n subplot of core ``Imaging`` dataset components. + + Panels: Data | Noise Map | Signal-To-Noise Map | PSF (if present) + + Parameters + ---------- + dataset + An ``Imaging`` dataset instance. + output_path + Directory to save the figure. ``None`` calls ``plt.show()``. + output_filename + Base filename without extension. + output_format + File format string or list, e.g. ``"png"`` or ``["png"]``. + """ + if isinstance(output_format, (list, tuple)): + output_format = output_format[0] + + panels = [ + (dataset.data, "Data"), + (dataset.noise_map, "Noise Map"), + (dataset.signal_to_noise_map, "Signal-To-Noise Map"), + ] + try: + panels.append((dataset.psf.kernel, "PSF")) + except Exception: + pass + + n = len(panels) + fig, axes = plt.subplots(1, n, figsize=(7 * n, 7)) + axes_flat = list(axes.flatten()) if n > 1 else [axes] + for i, (array, title) in enumerate(panels): + plot_array(array, ax=axes_flat[i], title=title) + plt.tight_layout() + subplot_save(fig, output_path, output_filename, output_format) + + +def subplot_imaging_dataset_list( + dataset_list, + output_path=None, + output_filename: str = "subplot_dataset_combined", + output_format="png", +): + """ + n×3 subplot showing core components for each dataset in a list. + + Each row shows: Data | Noise Map | Signal-To-Noise Map + + Parameters + ---------- + dataset_list + List of ``Imaging`` dataset instances. + output_path + Directory to save the figure. ``None`` calls ``plt.show()``. + output_filename + Base filename without extension. + output_format + File format string or list, e.g. ``"png"`` or ``["png"]``. + """ + if isinstance(output_format, (list, tuple)): + output_format = output_format[0] + + n = len(dataset_list) + fig, axes = plt.subplots(n, 3, figsize=(21, 7 * n)) + if n == 1: + axes = [axes] + for i, dataset in enumerate(dataset_list): + plot_array(dataset.data, ax=axes[i][0], title="Data") + plot_array(dataset.noise_map, ax=axes[i][1], title="Noise Map") + plot_array(dataset.signal_to_noise_map, ax=axes[i][2], title="Signal-To-Noise Map") plt.tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/test_autoarray/plot/mat_plot/__init__.py b/test_autoarray/plot/mat_plot/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_autoarray/plot/mat_plot/test_mat_plot.py b/test_autoarray/plot/mat_plot/test_mat_plot.py deleted file mode 100644 index c6c4bb68e..000000000 --- a/test_autoarray/plot/mat_plot/test_mat_plot.py +++ /dev/null @@ -1,2 +0,0 @@ -# MatPlot1D and MatPlot2D have been removed. -# Configuration is now done via direct wrapper objects passed to plotters. diff --git a/test_autoarray/plot/test_multi_plotters.py b/test_autoarray/plot/test_multi_plotters.py deleted file mode 100644 index dc4cb2f12..000000000 --- a/test_autoarray/plot/test_multi_plotters.py +++ /dev/null @@ -1,2 +0,0 @@ -# MultiFigurePlotter and MultiYX1DPlotter have been removed. -# Users should write their own matplotlib code for multi-panel plots. diff --git a/test_autoarray/plot/wrap/base/test_output.py b/test_autoarray/plot/test_output.py similarity index 95% rename from test_autoarray/plot/wrap/base/test_output.py rename to test_autoarray/plot/test_output.py index 2bbc41eb1..5405483b2 100644 --- a/test_autoarray/plot/wrap/base/test_output.py +++ b/test_autoarray/plot/test_output.py @@ -1,43 +1,43 @@ -import autoarray.plot as aplt - -from os import path - -import shutil - -directory = path.dirname(path.realpath(__file__)) - - -def test__constructor(): - output = aplt.Output() - - assert output.path == None - assert output._format == None - assert output.format == "show" - assert output.filename == None - - output = aplt.Output(path="Path", format="png", filename="file") - - assert output.path == "Path" - assert output._format == "png" - assert output.format == "png" - assert output.filename == "file" - - if path.exists(output.path): - shutil.rmtree(output.path) - - -def test__input_path_is_created(): - test_path = path.join(directory, "files", "output_path") - - if path.exists(test_path): - shutil.rmtree(test_path) - - assert not path.exists(test_path) - - output = aplt.Output( - path=test_path, - format="png", - ) - output.to_figure(structure=None, auto_filename="test") - - assert path.exists(test_path) +import autoarray.plot as aplt + +from os import path + +import shutil + +directory = path.dirname(path.realpath(__file__)) + + +def test__constructor(): + output = aplt.Output() + + assert output.path == None + assert output._format == None + assert output.format == "show" + assert output.filename == None + + output = aplt.Output(path="Path", format="png", filename="file") + + assert output.path == "Path" + assert output._format == "png" + assert output.format == "png" + assert output.filename == "file" + + if path.exists(output.path): + shutil.rmtree(output.path) + + +def test__input_path_is_created(): + test_path = path.join(directory, "files", "output_path") + + if path.exists(test_path): + shutil.rmtree(test_path) + + assert not path.exists(test_path) + + output = aplt.Output( + path=test_path, + format="png", + ) + output.to_figure(structure=None, auto_filename="test") + + assert path.exists(test_path) diff --git a/test_autoarray/plot/visuals/__init__.py b/test_autoarray/plot/visuals/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_autoarray/plot/visuals/test_visuals.py b/test_autoarray/plot/visuals/test_visuals.py deleted file mode 100644 index 9976631c5..000000000 --- a/test_autoarray/plot/visuals/test_visuals.py +++ /dev/null @@ -1,2 +0,0 @@ -# Visuals classes (Visuals1D, Visuals2D) have been removed. -# Overlay objects are now passed directly to Plotter constructors. diff --git a/test_autoarray/plot/wrap/__init__.py b/test_autoarray/plot/wrap/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_autoarray/plot/wrap/base/__init__.py b/test_autoarray/plot/wrap/base/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_autoarray/plot/wrap/one_d/__init__.py b/test_autoarray/plot/wrap/one_d/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_autoarray/plot/wrap/two_d/__init__.py b/test_autoarray/plot/wrap/two_d/__init__.py deleted file mode 100644 index e69de29bb..000000000