From dd02a55a0bf41ffbd6729950e86a85996238b061 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Tue, 7 Apr 2026 08:41:01 +0100 Subject: [PATCH] feat: add tight_layout wrapper with PYAUTO_FAST_PLOTS env var When PYAUTO_FAST_PLOTS=1, skip plt.tight_layout() in all subplot functions. This avoids expensive matplotlib font discovery and text metrics computation (~0.5-1s per subplot figure), cutting smoke test times significantly while preserving full code coverage. Co-Authored-By: Claude Opus 4.6 (1M context) --- autoarray/dataset/plot/imaging_plots.py | 6 +++--- autoarray/dataset/plot/interferometer_plots.py | 6 +++--- autoarray/fit/plot/fit_imaging_plots.py | 4 ++-- autoarray/fit/plot/fit_interferometer_plots.py | 6 +++--- autoarray/inversion/plot/inversion_plots.py | 6 +++--- autoarray/inversion/plot/mapper_plots.py | 4 ++-- autoarray/plot/__init__.py | 1 + autoarray/plot/utils.py | 12 ++++++++++++ 8 files changed, 29 insertions(+), 16 deletions(-) diff --git a/autoarray/dataset/plot/imaging_plots.py b/autoarray/dataset/plot/imaging_plots.py index 4271adb1..095c9704 100644 --- a/autoarray/dataset/plot/imaging_plots.py +++ b/autoarray/dataset/plot/imaging_plots.py @@ -2,7 +2,7 @@ import matplotlib.pyplot as plt -from autoarray.plot.utils import subplot_save, conf_subplot_figsize +from autoarray.plot.utils import subplot_save, conf_subplot_figsize, tight_layout def subplot_imaging_dataset( @@ -139,7 +139,7 @@ def subplot_imaging_dataset( from autoarray.plot.utils import hide_unused_axes hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) @@ -179,7 +179,7 @@ def subplot_imaging_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() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/autoarray/dataset/plot/interferometer_plots.py b/autoarray/dataset/plot/interferometer_plots.py index 33e336a0..87c751cd 100644 --- a/autoarray/dataset/plot/interferometer_plots.py +++ b/autoarray/dataset/plot/interferometer_plots.py @@ -6,7 +6,7 @@ from autoarray.plot.array import plot_array from autoarray.plot.grid import plot_grid from autoarray.plot.yx import plot_yx -from autoarray.plot.utils import subplot_save, hide_unused_axes, conf_subplot_figsize +from autoarray.plot.utils import subplot_save, hide_unused_axes, conf_subplot_figsize, tight_layout from autoarray.structures.grids.irregular_2d import Grid2DIrregular @@ -87,7 +87,7 @@ def subplot_interferometer_dataset( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) @@ -142,7 +142,7 @@ def subplot_interferometer_dirty_images( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/autoarray/fit/plot/fit_imaging_plots.py b/autoarray/fit/plot/fit_imaging_plots.py index faa471f3..298d6ccd 100644 --- a/autoarray/fit/plot/fit_imaging_plots.py +++ b/autoarray/fit/plot/fit_imaging_plots.py @@ -3,7 +3,7 @@ import matplotlib.pyplot as plt from autoarray.plot.array import plot_array -from autoarray.plot.utils import subplot_save, symmetric_vmin_vmax, hide_unused_axes, conf_subplot_figsize +from autoarray.plot.utils import subplot_save, symmetric_vmin_vmax, hide_unused_axes, conf_subplot_figsize, tight_layout def subplot_fit_imaging( @@ -121,5 +121,5 @@ def subplot_fit_imaging( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/autoarray/fit/plot/fit_interferometer_plots.py b/autoarray/fit/plot/fit_interferometer_plots.py index 136122d2..15f29fe0 100644 --- a/autoarray/fit/plot/fit_interferometer_plots.py +++ b/autoarray/fit/plot/fit_interferometer_plots.py @@ -5,7 +5,7 @@ from autoarray.plot.array import plot_array from autoarray.plot.yx import plot_yx -from autoarray.plot.utils import subplot_save, symmetric_vmin_vmax, hide_unused_axes, conf_subplot_figsize +from autoarray.plot.utils import subplot_save, symmetric_vmin_vmax, hide_unused_axes, conf_subplot_figsize, tight_layout def subplot_fit_interferometer( @@ -99,7 +99,7 @@ def subplot_fit_interferometer( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) @@ -195,5 +195,5 @@ def subplot_fit_interferometer_dirty_images( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/autoarray/inversion/plot/inversion_plots.py b/autoarray/inversion/plot/inversion_plots.py index e57d412f..e6e55ac5 100644 --- a/autoarray/inversion/plot/inversion_plots.py +++ b/autoarray/inversion/plot/inversion_plots.py @@ -9,7 +9,7 @@ from autoarray.inversion.mappers.abstract import Mapper from autoarray.plot.array import plot_array -from autoarray.plot.utils import numpy_grid, numpy_lines, numpy_positions, subplot_save, hide_unused_axes, conf_subplot_figsize +from autoarray.plot.utils import numpy_grid, numpy_lines, numpy_positions, subplot_save, hide_unused_axes, conf_subplot_figsize, tight_layout from autoarray.inversion.plot.mapper_plots import plot_mapper from autoarray.structures.arrays.uniform_2d import Array2D @@ -224,7 +224,7 @@ def _recon_array(): pass hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, f"{output_filename}_{mapper_index}", output_format) @@ -342,7 +342,7 @@ def subplot_mappings( ) hide_unused_axes(axes) - plt.tight_layout() + tight_layout() subplot_save( fig, output_path, f"{output_filename}_{pixelization_index}", output_format ) diff --git a/autoarray/inversion/plot/mapper_plots.py b/autoarray/inversion/plot/mapper_plots.py index 7a7e5007..088d10c5 100644 --- a/autoarray/inversion/plot/mapper_plots.py +++ b/autoarray/inversion/plot/mapper_plots.py @@ -5,7 +5,7 @@ from autoarray.plot.array import plot_array from autoarray.plot.inversion import plot_inversion_reconstruction -from autoarray.plot.utils import numpy_grid, numpy_lines, subplot_save, conf_subplot_figsize +from autoarray.plot.utils import numpy_grid, numpy_lines, subplot_save, conf_subplot_figsize, tight_layout logger = logging.getLogger(__name__) @@ -133,5 +133,5 @@ def subplot_image_and_mapper( ax=axes[1], ) - plt.tight_layout() + tight_layout() subplot_save(fig, output_path, output_filename, output_format) diff --git a/autoarray/plot/__init__.py b/autoarray/plot/__init__.py index a4847c12..4b219309 100644 --- a/autoarray/plot/__init__.py +++ b/autoarray/plot/__init__.py @@ -32,6 +32,7 @@ def _set_backend(): conf_mat_plot_fontsize, save_figure, subplot_save, + tight_layout, auto_mask_edge, zoom_array, numpy_grid, diff --git a/autoarray/plot/utils.py b/autoarray/plot/utils.py index f3438568..40623d1b 100644 --- a/autoarray/plot/utils.py +++ b/autoarray/plot/utils.py @@ -12,6 +12,18 @@ logger = logging.getLogger(__name__) +def tight_layout(): + """Call ``plt.tight_layout()`` unless fast-plot mode is active. + + When ``PYAUTO_FAST_PLOTS=1`` the expensive layout-optimisation pass + is skipped. All figure creation, data computation, and rendering + still execute — only the final spacing adjustment is bypassed. + """ + if os.environ.get("PYAUTO_FAST_PLOTS") == "1": + return + plt.tight_layout() + + # --------------------------------------------------------------------------- # autoarray → numpy conversion helpers (used by high-level plot functions) # ---------------------------------------------------------------------------