2D colormaps¶
Python¶
Use a two-dimensional colormap when one array supplies the lightness and a second array supplies the hue. For two measurements with matching coordinates:
import xarray as xr
import erlab.plotting as eplt
data_a, data_b = xr.align(data_a, data_b, join="exact")
intensity = data_a + data_b
asymmetry = ((data_a - data_b) / intensity).where(intensity > 0)
Plot the two quantities separately first. Check where low total intensity makes the normalized difference unstable:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(
1,
2,
figsize=(7.2, 3.0),
layout="compressed",
sharex=True,
sharey=True,
)
intensity_image = eplt.plot_array(
intensity,
ax=axes[0],
cmap="viridis",
aspect="equal",
)
asymmetry_image = eplt.plot_array(
asymmetry,
ax=axes[1],
cmap="bwr",
norm=eplt.CenteredPowerNorm(1.0, vcenter=0.0, halfrange=1.0),
aspect="equal",
)
eplt.nice_colorbar(ax=axes[0], mappable=intensity_image, width=7)
eplt.nice_colorbar(ax=axes[1], mappable=asymmetry_image, width=7)
eplt.set_titles(axes, ["Total intensity", "Normalized difference"])
eplt.clean_labels(axes)
Map total intensity to lightness and normalized difference to hue:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(4.8, 3.4), layout="compressed")
_, colorbar = eplt.plot_array_2d(
intensity,
asymmetry,
ax=ax,
lnorm=eplt.InversePowerNorm(0.5),
cnorm=eplt.CenteredInversePowerNorm(0.7, vcenter=0.0, halfrange=1.0),
)
colorbar.ax.set_xticks(colorbar.ax.get_xlim(), labels=["Min", "Max"])
colorbar.ax.set(xlabel="Intensity", ylabel="Asymmetry")
Figure Composer¶
First calculate intensity and asymmetry with the Python code above. Open both arrays
in ImageTool Manager and add them as Figure Composer sources. The separate diagnostic
plots then use editable recipe steps:
Set Layout to a \(1 \times 2\) grid.
Add
intensityandasymmetryin Sources.Add one Image Plot step for each source and target one axes per step.
Set the intensity colormap to
viridis.Set the asymmetry colormap to
bwr. SelectCenteredPowerNorm, and set Gamma to1. Under Center/range, setvcenterto0andhalfrangeto1.Add one ERLab Method step with
nice_colorbarafter each image.Add
set_titlesandclean_labelsERLab Method steps.
The combined lightness-and-hue plot does not have an editable recipe step.
Planned Figure Composer support
Figure Composer does not yet have an editable step for this plotting operation. Structured support is planned. Until then, add a Python step to the recipe and use the code in this section.
Add
data_aanddata_bin Sources.Add a Python step to a \(1 \times 1\) figure.
Review this code, then enter it in Code:
data_a, data_b = xr.align(data_a, data_b, join="exact")
intensity = data_a + data_b
asymmetry = ((data_a - data_b) / intensity).where(intensity > 0)
_, colorbar = eplt.plot_array_2d(
intensity,
asymmetry,
ax=ax,
lnorm=eplt.InversePowerNorm(0.5),
cnorm=eplt.CenteredInversePowerNorm(0.7, vcenter=0.0, halfrange=1.0),
)
colorbar.ax.set_xticks(colorbar.ax.get_xlim(), labels=["Min", "Max"])
colorbar.ax.set(xlabel="Intensity", ylabel="Asymmetry")
Mask or otherwise handle points where the summed intensity is too small for a stable
normalized difference. Confirm that data_a and data_b have aligned coordinates
before calculating the asymmetry. The two-dimensional colorbar shows the independent
lightness and hue mappings.
See erlab.plotting.plot_array_2d() for color normalization and colorbar arguments.