Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions autoarray/config/visualize/general.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
general:
backend: default # The matplotlib backend used for visualization. `default` uses the system default, can specify specific backend (e.g. TKAgg, Qt5Agg, WXAgg).
dpi: 150 # Resolution in dots per inch used when saving figures. Lower values reduce file size (e.g. 150 gives ~50% smaller files than 300 with negligible quality loss for diagnostic subplots).
imshow_origin: upper # The `origin` input of `imshow`, determining if pixel values are ascending or descending on the y-axis.
log10_min_value: 1.0e-4 # If negative values are being plotted on a log10 scale, values below this value are rounded up to it (e.g. to remove negative values).
log10_max_value: 1.0e99 # If positive values are being plotted on a log10 scale, values above this value are rounded down to it.
Expand Down
14 changes: 10 additions & 4 deletions autoarray/inversion/plot/inversion_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,18 @@ def _recon_array():

# panels 4-5: source reconstruction zoomed / unzoomed
pixel_values = inversion.reconstruction_dict[mapper]
try:
recon_vmax = float(np.max(np.asarray(_recon_array())))
except Exception:
recon_vmax = None
plot_mapper(
mapper,
solution_vector=pixel_values,
ax=axes[4],
title="Source Reconstruction",
title="Source Plane (Zoom)",
colormap=colormap,
use_log10=use_log10,
vmax=recon_vmax,
zoom_to_brightest=True,
mesh_grid=mesh_grid,
lines=lines,
Expand All @@ -131,9 +136,10 @@ def _recon_array():
mapper,
solution_vector=pixel_values,
ax=axes[5],
title="Source Reconstruction (Unzoomed)",
title="Source Plane (No Zoom)",
colormap=colormap,
use_log10=use_log10,
vmax=recon_vmax,
zoom_to_brightest=False,
mesh_grid=mesh_grid,
lines=lines,
Expand Down Expand Up @@ -316,7 +322,7 @@ def subplot_mappings(
mapper,
solution_vector=pixel_values,
ax=axes[2],
title="Source Reconstruction",
title="Source Plane (Zoom)",
colormap=colormap,
use_log10=use_log10,
zoom_to_brightest=True,
Expand All @@ -327,7 +333,7 @@ def subplot_mappings(
mapper,
solution_vector=pixel_values,
ax=axes[3],
title="Source Reconstruction (Unzoomed)",
title="Source Plane (No Zoom)",
colormap=colormap,
use_log10=use_log10,
zoom_to_brightest=False,
Expand Down
4 changes: 4 additions & 0 deletions autoarray/inversion/plot/mapper_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def plot_mapper(
output_format: str = "png",
colormap=None,
use_log10: bool = False,
vmin=None,
vmax=None,
mesh_grid=None,
lines=None,
line_colors=None,
Expand Down Expand Up @@ -63,6 +65,8 @@ def plot_mapper(
title=title,
colormap=colormap,
use_log10=use_log10,
vmin=vmin,
vmax=vmax,
zoom_to_brightest=zoom_to_brightest,
lines=numpy_lines(lines),
line_colors=line_colors,
Expand Down
13 changes: 11 additions & 2 deletions autoarray/plot/inversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def plot_inversion_reconstruction(
elif isinstance(
mapper.interpolator, (InterpolatorDelaunay, InterpolatorKNearestNeighbor)
):
_plot_delaunay(ax, pixel_values, mapper, norm, colormap, is_subplot=is_subplot)
_plot_delaunay(ax, pixel_values, mapper, norm, colormap, extent, is_subplot=is_subplot)

# --- overlays --------------------------------------------------------------
if lines is not None:
Expand Down Expand Up @@ -230,7 +230,7 @@ def _plot_rectangular(ax, pixel_values, mapper, norm, colormap, extent, is_subpl
_apply_colorbar(im, ax, is_subplot=is_subplot)


def _plot_delaunay(ax, pixel_values, mapper, norm, colormap, is_subplot=False):
def _plot_delaunay(ax, pixel_values, mapper, norm, colormap, extent, is_subplot=False):
"""Render a Delaunay or KNN pixelization reconstruction onto *ax*.

Uses ``ax.tripcolor`` with Gouraud shading so that the reconstructed
Expand All @@ -252,10 +252,19 @@ def _plot_delaunay(ax, pixel_values, mapper, norm, colormap, is_subplot=False):
``None`` for automatic scaling.
colormap
Matplotlib colormap name.
extent
``[xmin, xmax, ymin, ymax]`` spatial extent; used to set the axes
aspect ratio to match rectangular pixelization plots.
is_subplot
When ``True`` uses ``labelsize_subplot`` from config for the colorbar
tick labels (matches the behaviour of :func:`~autoarray.plot.array.plot_array`).
"""
xmin, xmax, ymin, ymax = extent
x_range = abs(xmax - xmin)
y_range = abs(ymax - ymin)
box_aspect = (x_range / y_range) if y_range > 0 else 1.0
ax.set_aspect(box_aspect, adjustable="box")

mesh_grid = mapper.source_plane_mesh_grid

if hasattr(mesh_grid, "array"):
Expand Down
19 changes: 16 additions & 3 deletions autoarray/plot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def save_figure(
path: str,
filename: str,
format: str = "png",
dpi: int = 300,
dpi: Optional[int] = None,
structure=None,
) -> None:
"""
Expand Down Expand Up @@ -448,6 +448,10 @@ def save_figure(
of ``fig.savefig``. Callers do not need to pass this; ``plot_array``
supplies it automatically from the input array.
"""
if dpi is None:
from autoconf import conf
dpi = int(conf.instance["visualize"]["general"]["general"]["dpi"])

if path:
os.makedirs(path, exist_ok=True)
formats = format if isinstance(format, (list, tuple)) else [format]
Expand Down Expand Up @@ -717,11 +721,20 @@ def _inward_ticks(lo: float, hi: float, factor: float, n: int) -> np.ndarray:


def _round_ticks(values: np.ndarray, sig: int = 2) -> np.ndarray:
"""Round *values* to *sig* significant figures."""
"""Round *values* to *sig* significant figures.

After rounding, values smaller than 1e-10 of the overall tick scale are
clamped to zero so that floating-point noise (e.g. 1e-16 centre ticks on
symmetric extents) does not appear as scientific notation in labels.
"""
with np.errstate(divide="ignore", invalid="ignore"):
nonzero = np.where(values != 0, np.abs(values), 1.0)
mags = np.where(values != 0, 10 ** (sig - 1 - np.floor(np.log10(nonzero))), 1.0)
return np.round(values * mags) / mags
rounded = np.round(values * mags) / mags
scale = float(np.max(np.abs(rounded))) if len(rounded) > 0 else 1.0
if scale > 0:
rounded[np.abs(rounded) < scale * 1e-10] = 0.0
return rounded


def _arcsec_labels(ticks) -> List[str]:
Expand Down
Loading