"""Multi-panel comparison plots."""
import numpy as np
import matplotlib.pyplot as plt
from ._common import format_colorbar_scientific, _maybe_slice_level
[docs]
def plot_field_comparison(
fields, domain, src_pt=None, cmap="turbo", figsize=None, level=0
):
"""2x2 panel comparison: conc, flux, and relative differences.
Top-left: concentration, top-right: flux.
Bottom-left: relative difference concentration, bottom-right: relative difference flux.
Parameters
----------
fields : dict
Must contain keys: "conc", "flx", "conc_ref", "flx_ref".
Values may be 2-D or 3-D arrays. If 3D, sliced at *level*.
domain : tuple (xmax, ymax)
Domain extents for imshow.
src_pt : tuple (x, y), optional
Source point coordinates to mark with a red star on top panels.
cmap : str
Colormap name (default "turbo").
figsize : tuple, optional
Figure size (width, height). Default (10, 6).
level : int
Z-index to use when fields are 3D. Default 0 (surface).
Returns
-------
fig : matplotlib Figure
axes : ndarray of Axes (2x2)
"""
if figsize is None:
figsize = (10, 6)
conc = fields["conc"]
flx = fields["flx"]
conc_ref = fields["conc_ref"]
flx_ref = fields["flx_ref"]
if conc.ndim == 3:
conc = conc[level]
if flx.ndim == 3:
flx = flx[level]
if conc_ref.ndim == 3:
conc_ref = conc_ref[level]
if flx_ref.ndim == 3:
flx_ref = flx_ref[level]
diff_conc = (conc - conc_ref) / np.max(conc_ref)
diff_flx = (flx - flx_ref) / np.max(flx_ref)
extent = [0, domain[0], 0, domain[1]]
shrink = 0.7
fig, axs = plt.subplots(
2, 2, figsize=figsize, sharex=True, sharey=True, layout="constrained"
)
# Top-left: concentration
plot = axs[0, 0].imshow(conc, origin="lower", cmap=cmap, extent=extent)
axs[0, 0].set_title("Numerical concentration")
axs[0, 0].set_ylabel("y [m]")
axs[0, 0].xaxis.set_tick_params(labelbottom=False)
cbar = fig.colorbar(plot, ax=axs[0, 0], shrink=shrink, location="bottom")
format_colorbar_scientific(cbar, "a.u.")
# Top-right: flux
plot = axs[0, 1].imshow(flx, origin="lower", cmap=cmap, extent=extent)
axs[0, 1].set_title("Numerical flux")
axs[0, 1].xaxis.set_tick_params(labelbottom=False)
axs[0, 1].yaxis.set_tick_params(labelleft=False)
cbar = fig.colorbar(plot, ax=axs[0, 1], shrink=shrink, location="bottom")
format_colorbar_scientific(cbar, "a.u. m/s")
# Bottom-left: relative difference concentration
plot = axs[1, 0].imshow(diff_conc, origin="lower", cmap=cmap, extent=extent)
axs[1, 0].set_title("Relative difference to analytic concentration")
axs[1, 0].set_xlabel("x [m]")
axs[1, 0].set_ylabel("y [m]")
cbar = fig.colorbar(plot, ax=axs[1, 0], shrink=shrink, location="bottom")
format_colorbar_scientific(cbar)
# Bottom-right: relative difference flux
plot = axs[1, 1].imshow(diff_flx, origin="lower", cmap=cmap, extent=extent)
axs[1, 1].set_title("Relative difference to analytic flux")
axs[1, 1].set_xlabel("x [m]")
axs[1, 1].yaxis.set_tick_params(labelleft=False)
cbar = fig.colorbar(plot, ax=axs[1, 1], shrink=shrink, location="bottom")
format_colorbar_scientific(cbar)
if src_pt is not None:
axs[0, 0].scatter(
src_pt[0], src_pt[1], zorder=5, marker="*", color="red", s=100
)
axs[0, 1].scatter(
src_pt[0], src_pt[1], zorder=5, marker="*", color="red", s=100
)
return fig, axs