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
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,25 @@ def plot_setting(section: Union[List[str], str], name: str) -> bool:
return setting(section, name)


class PlotterInterface:
class Plotter:
def __init__(self, image_path: Union[Path, str], title_prefix: str = None):
"""
Base class for all plotters, which output visualizations during a model fit.

The methods of the `Plotter` are called throughout a non-linear search via the
`Analysis` class `visualize` method.

The images output by the `Plotter` are customized using the file
`config/visualize/plots.yaml`.

Parameters
----------
image_path
The path on the hard-disk to the `image` folder of the non-linear search
results where all visualizations are saved.
title_prefix
An optional string prefixed to every plot title.
"""
from pathlib import Path

self.image_path = Path(image_path)
Expand All @@ -49,16 +66,33 @@ def __init__(self, image_path: Union[Path, str], title_prefix: str = None):

@property
def fmt(self) -> List[str]:
"""The output file format(s) read from ``config/visualize/plots.yaml``."""
return conf.instance["visualize"]["plots"]["subplot_format"]

def output_from(self) -> aplt.Output:
"""Return an ``autoarray`` ``Output`` object pointed at ``image_path``."""
return aplt.Output(path=self.image_path, format=self.fmt)

def galaxies(
self,
galaxies: List[Galaxy],
grid: aa.type.Grid2DLike,
):
"""
Output visualization of a list of galaxies.

Controlled by the ``[galaxies]`` section of ``config/visualize/plots.yaml``.
Outputs include galaxy image subplots and, when enabled, a FITS file of each
galaxy image.

Parameters
----------
galaxies
The list of galaxies to visualize.
grid
A 2D grid of (y, x) arc-second coordinates used to evaluate each galaxy
image.
"""
galaxies = Galaxies(galaxies=galaxies)

def should_plot(name):
Expand Down Expand Up @@ -94,6 +128,18 @@ def should_plot(name):
hdu_list.writeto(self.image_path / "galaxy_images.fits", overwrite=True)

def inversion(self, inversion: aa.Inversion):
"""
Output visualization of an ``Inversion``.

Controlled by the ``[inversion]`` section of ``config/visualize/plots.yaml``.
When enabled, outputs a scatter-plot of each mapper's source-plane
reconstruction and a CSV of the reconstruction values and noise map.

Parameters
----------
inversion
The inversion whose reconstruction is visualized.
"""
def should_plot(name):
return plot_setting(section="inversion", name=name)

Expand Down Expand Up @@ -144,6 +190,19 @@ def should_plot(name):
)

def adapt_images(self, adapt_images: AdaptImages):
"""
Output visualization of adapt images from a previous model-fit search.

Controlled by the ``[adapt]`` section of ``config/visualize/plots.yaml``.
Outputs a subplot of the per-galaxy adapt images and, when enabled, FITS files
of the adapt images and image-plane mesh grids.

Parameters
----------
adapt_images
The adapt images containing per-galaxy images used to drive adaptive mesh
and regularization schemes.
"""
def should_plot(name):
return plot_setting(section="adapt", name=name)

Expand Down
12 changes: 6 additions & 6 deletions autogalaxy/config/visualize/plots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
subplot_format: [png] # Output format of all subplots, can be png, pdf or both (e.g. [png, pdf])
fits_are_zoomed: false # If true, output .fits files are zoomed in on the center of the unmasked region image, saving hard-disk space.

dataset: # Settings for plots of all datasets (e.g. ImagingPlotter, InterferometerPlotter).
dataset: # Settings for plots of all datasets (e.g. Imaging, Interferometer).
subplot_dataset: true # Plot subplot containing all dataset quantities (e.g. the data, noise-map, etc.)?
fits_dataset: true # Output a .fits file containing the dataset data, noise-map and other quantities?

fit: # Settings for plots of all fits (e.g. FitImagingPlotter, FitInterferometerPlotter).
fit: # Settings for plots of all fits (e.g. FitImaging, FitInterferometer).
subplot_fit: true # Plot subplot of all fit quantities for any dataset (e.g. the model data, residual-map, etc.)?
subplot_fit_log10: true # Plot subplot of all fit quantities for any dataset using log10 color maps (e.g. the model data, residual-map, etc.)?
subplot_of_galaxies: false # Plot subplot of the model-image, subtracted image and other quantities of each galaxy?
Expand All @@ -26,9 +26,9 @@ fit: # Settings for plots of all fits (e.g
fits_galaxy_images : true # Output a .fits file containing the images (e.g. without PSF convolution) of every galaxy?
fits_model_galaxy_images : true # Output a .fits file containing the model images (e.g. with PSF convolution) of every galaxy?

fit_imaging: {} # Settings for plots of fits to imaging datasets (e.g. FitImagingPlotter).
fit_imaging: {} # Settings for plots of fits to imaging datasets (e.g. FitImaging).

galaxies: # Settings for plots of galaxies (e.g. GalaxiesPlotter).
galaxies: # Settings for plots of galaxies (e.g. Galaxies).
subplot_galaxies: true # Plot subplot of all quantities in each galaxies group (e.g. images, convergence)?
subplot_galaxy_images: false # Plot subplot of the image of each galaxy in the model?
fits_galaxy_images: false # Output a .fits file containing images of every galaxy?
Expand All @@ -42,7 +42,7 @@ adapt: # Settings for plots of adapt images
subplot_adapt_images: true # Plot subplot showing each adapt image used for adaptive pixelization?
fits_adapt_images: true # Output a .fits file containing the adapt images used for adaptive pixelization?

fit_interferometer: # Settings for plots of fits to interferometer datasets (e.g. FitInterferometerPlotter).
fit_interferometer: # Settings for plots of fits to interferometer datasets (e.g. FitInterferometer).
subplot_fit_dirty_images: false # Plot subplot of the dirty-images of all interferometer datasets?
subplot_fit_real_space: false # Plot subplot of the real-space images of all interferometer datasets?
fits_dirty_images: true # output dirty_images.fits showing the dirty image, noise-map, model-data, resiual-map, normalized residual map and chi-squared map?
Expand All @@ -53,4 +53,4 @@ fit_ellipse: # Settings for plots of ellipse fitti
data_no_ellipse: true # Plot the data without the black data ellipses, which obscure noisy data?
ellipse_residuals: true # Plot the residuals of the ellipse fit?

fit_quantity: {} # Settings for plots of fit quantities (e.g. FitQuantityPlotter).
fit_quantity: {} # Settings for plots of fit quantities (e.g. FitQuantity).
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
import matplotlib.pyplot as plt
from typing import List

from autoconf.fitsable import hdu_list_for_output_from

import autoarray as aa
import autoarray.plot as aplt

from autoarray.dataset.plot.imaging_plots import subplot_imaging

from autogalaxy.ellipse.fit_ellipse import FitEllipse
from autogalaxy.ellipse.plot import fit_ellipse_plots
from autogalaxy.analysis.plotter_interface import PlotterInterface, plot_setting
from autogalaxy.plot.plot_utils import plot_array, _save_subplot
from autogalaxy.analysis.plotter import Plotter, plot_setting


class PlotterInterfaceEllipse(PlotterInterface):
class PlotterEllipse(Plotter):
def imaging(self, dataset: aa.Imaging):
"""
Output visualization of an ``Imaging`` dataset for ellipse fitting.

Controlled by the ``[dataset]`` / ``[imaging]`` sections of
``config/visualize/plots.yaml``. Outputs a subplot of the imaging data
and a FITS file containing the mask, data, and noise-map arrays.

Parameters
----------
dataset
The imaging dataset to visualize.
"""
def should_plot(name):
return plot_setting(section=["dataset", "imaging"], name=name)

if should_plot("subplot_dataset"):
panels = [
(dataset.data, "Data"),
(dataset.noise_map, "Noise Map"),
(dataset.signal_to_noise_map, "Signal-To-Noise Map"),
]
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, title, ax=axes_flat[i])
plt.tight_layout()
_save_subplot(fig, self.image_path, "subplot_dataset", self.fmt)
subplot_imaging(
dataset,
output_path=self.image_path,
output_format=self.fmt,
)

image_list = [
dataset.data.native,
Expand All @@ -52,6 +56,18 @@ def fit_ellipse(
self,
fit_list: List[FitEllipse],
):
"""
Output visualization of a list of ``FitEllipse`` objects.

Controlled by the ``[fit]`` / ``[fit_ellipse]`` sections of
``config/visualize/plots.yaml``. Outputs data images with ellipse
overlays, ellipse residual plots, and a combined fit subplot.

Parameters
----------
fit_list
The list of ellipse fits to visualize (one per ellipse).
"""
def should_plot(name):
return plot_setting(section=["fit", "fit_ellipse"], name=name)

Expand Down
6 changes: 3 additions & 3 deletions autogalaxy/ellipse/model/visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from autoarray import exc

from autogalaxy.ellipse.model.plotter_interface import PlotterInterfaceEllipse
from autogalaxy.ellipse.model.plotter import PlotterEllipse


class VisualizerEllipse(af.Visualizer):
Expand All @@ -27,7 +27,7 @@ def visualize_before_fit(
the imaging data.
"""

plotter = PlotterInterfaceEllipse(
plotter = PlotterEllipse(
image_path=paths.image_path, title_prefix=analysis.title_prefix
)

Expand Down Expand Up @@ -63,7 +63,7 @@ def visualize(
"""
fit_list = analysis.fit_list_from(instance=instance)

plotter = PlotterInterfaceEllipse(
plotter = PlotterEllipse(
image_path=paths.image_path, title_prefix=analysis.title_prefix
)
plotter.imaging(dataset=analysis.dataset)
Expand Down
4 changes: 2 additions & 2 deletions autogalaxy/imaging/fit_imaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def galaxies_linear_light_profiles_to_light_profiles(self) -> List[Galaxy]:
The galaxy list where all linear light profiles have been converted to ordinary light profiles, where their
`intensity` values are set to the values inferred by this fit.

This is typically used for visualization, because linear light profiles cannot be used in `LightProfilePlotter`
or `GalaxyPlotter` objects.
This is typically used for visualization, because linear light profiles cannot be used in `LightProfile`
or `Galaxy` objects.
"""
return self.model_obj_linear_light_profiles_to_light_profiles
Loading
Loading