Source code for ixdat.plotters.sec_plotter

import matplotlib as mpl

from .base_mpl_plotter import MPLPlotter
from .ec_plotter import ECPlotter
from .spectrum_plotter import SpectrumSeriesPlotter
from ..exceptions import SeriesNotFoundError


[docs]class SECPlotter(MPLPlotter): """An spectroelectrochemsitry (SEC) matplotlib plotter. FIXME: This should make use of the code in spectrum_plotter.SpectrumSeriesPlotter """ def __init__(self, measurement=None): """Initiate the plotter with its default Meausurement to plot""" self.measurement = measurement self.ec_plotter = ECPlotter(measurement=measurement) self.spectrum_series_plotter = SpectrumSeriesPlotter( spectrum_series=self.measurement # FIXME: Maybe SpectrumSeries should inherit from Measurement? )
[docs] def plot_measurement( self, measurement=None, tspan=None, wlspan=None, axes=None, V_ref=None, t_ref=None, cmap_name="inferno", make_colorbar=False, **kwargs, ): """Plot an SECMeasurement in two panels with time as x-asis. The top panel is a heat plot with wavelength on y-axis and color representing spectrum. At most one of V_ref and t_ref should be given, and if neither are given the measurement's default reference_spectrum is used to calculate the optical density. Args: measurement (Measurement): The measurement to be plotted, if different from self.measurement tspan (timespan): The timespan of data to keep for the measurement. wlspan (iterable): The wavelength span of spectral data to plot axes (list of mpl.Axis): The axes to plot on. axes[0] is for the heat plot, axes[1] for potential, and axes[2] for current. The axes are optional and a new set of axes, where axes[1] and axes[2] are twinned on x, are generated if not provided. V_ref (float): potential to use as reference for calculating optical density t_ref (float): time to use as a reference for calculating optical density cmap_name (str): The name of the colormap to use. Defaults to "inferno", which ranges from black through red and orange to yellow-white. "jet" is also good. make_colorbar (bool): Whether to make a colorbar. FIXME: colorbar at present mis-alignes axes kwargs: Additional key-word arguments are passed on to ECPlotter.plot_measurement(). """ measurement = measurement or self.measurement if not axes: axes = self.new_two_panel_axes(n_bottom=2, n_top=1, emphasis="top",) self.ec_plotter.plot_measurement( measurement=measurement, axes=[axes[1], axes[2]], tspan=tspan, **kwargs, ) dOD_series = measurement.calc_dOD(V_ref=V_ref, t_ref=t_ref) axes[0] = self.spectrum_series_plotter.heat_plot( field=dOD_series, tspan=tspan, xspan=wlspan, ax=axes[0], cmap_name=cmap_name, make_colorbar=make_colorbar, ) if make_colorbar: pass # TODO: adjust EC plot to be same width as heat plot despite colorbar. axes[1].set_xlim(axes[0].get_xlim()) return axes
[docs] def plot_waterfall( self, measurement=None, ax=None, V_ref=None, t_ref=None, cmap_name="jet", make_colorbar=True, ): """Plot an SECMeasurement as spectra colored based on potential. The top panel is a heat plot with wavelength on y-axis and color representing spectrum. At most one of V_ref and t_ref should be given, and if neither are given the measurement's default reference_spectrum is used to calculate the optical density. This uses SpectrumSeriesPlotter.plot_waterfall() Args: measurement (Measurement): The measurement to be plotted, if different from self.measurement tspan (timespan): The timespan of data to keep for the measurement. wlspan (iterable): The wavelength span of spectral data to plot ax (matplotlib Axis): The axes to plot on. A new one is made by default. V_ref (float): potential to use as reference for calculating optical density t_ref (float): time to use as a reference for calculating optical density cmap_name (str): The name of the colormap to use. Defaults to "inferno", which ranges from black through red and orange to yellow-white. "jet" is also good. make_colorbar (bool): Whether to make a colorbar. """ measurement = measurement or self.measurement dOD = measurement.calc_dOD(V_ref=V_ref, t_ref=t_ref) return self.spectrum_series_plotter.plot_waterfall( field=dOD, cmap_name=cmap_name, make_colorbar=make_colorbar, ax=ax, vs=measurement.V_str, )
[docs] def plot_vs_potential( self, measurement=None, tspan=None, vspan=None, V_str=None, J_str=None, axes=None, wlspan=None, V_ref=None, cmap_name="inferno", make_colorbar=False, **kwargs, ): """Plot an SECMeasurement in two panels with potential as x-asis. The top panel is a heat plot with wavelength on y-axis and color representing spectrum. At most one of V_ref and t_ref should be given, and if neither are given the measurement's default reference_spectrum is used to calculate the optical density. Args: measurement (Measurement): The measurement to be plotted, if different from self.measurement tspan (timespan): The timespan of data to keep for the measurement. vspan (timespan): The potential span of data to keep for the measurement. V_str (str): Optional. The name of the data series to use as potential. J_str (str): Optional. The name of the data series to use as current. wlspan (iterable): The wavelength span of spectral data to plot axes (list of numpy Axes): The axes to plot on. axes[0] is for the heat plot and axes[1] for potential. New are made by default. V_ref (float): potential to use as reference for calculating optical density t_ref (float): time to use as a reference for calculating optical density cmap_name (str): The name of the colormap to use. Defaults to "inferno", which ranges from black through red and orange to yellow-white. "jet" is also good. make_colorbar (bool): Whether to make a colorbar. kwargs: Additional key-word arguments are passed on to ECPlotter.plot_vs_potential(). """ measurement = measurement or self.measurement if not axes: axes = self.new_two_panel_axes(n_bottom=1, n_top=1, emphasis="top",) self.ec_plotter.plot_vs_potential( measurement=measurement, tspan=tspan, V_str=V_str, J_str=J_str, ax=axes[1], **kwargs, ) dOD_series = measurement.calc_dOD(V_ref=V_ref) axes[0] = self.spectrum_series_plotter.heat_plot_vs( field=dOD_series, vspan=vspan, xspan=wlspan, ax=axes[0], cmap_name=cmap_name, make_colorbar=make_colorbar, vs=V_str or measurement.V_str, ) axes[1].set_xlim(axes[0].get_xlim()) return axes
[docs] def plot_wavelengths( self, measurement=None, wavelengths=None, axes=None, cmap_name="jet", tspan=None, **kwargs, ): """Plot the dO.D. for specific wavelength in the top panel and EC in bottom Args: measurement (Measurement): The measurement to be plotted, if different from self.measurement wavelengths (list of str): The names of the wavelengths to track as strings, e.g. "w400" for 400 nm axes (list of Ax): The axes to plot on, defaults to new matplotlib axes cmap_name (str): Name of the colormap. Defaults to "jet" tspan (timespan): The timespan to plot **kwargs: Additional key-word arguments are passed on to ECPlotter.plot_measurement """ measurement = measurement or self.measurement wavelengths = wavelengths or measurement.tracked_wavelengths cmap = mpl.cm.get_cmap(cmap_name) norm = mpl.colors.Normalize(vmin=min(measurement.wl), vmax=max(measurement.wl)) if not axes: axes = self.new_two_panel_axes(n_bottom=2) for wl_str in wavelengths: x = float(wl_str[1:]) try: t, y = measurement.grab(wl_str, tspan=tspan) except SeriesNotFoundError: measurement.track_wavelength(x) t, y = measurement.grab(wl_str, tspan=tspan) axes[0].plot(t, y, color=cmap(norm(x)), label=wl_str) axes[0].legend() axes[0].set_ylabel("$\Delta$O.D.") self.ec_plotter.plot_measurement( measurement=measurement, axes=axes[1:], tspan=tspan, **kwargs )
[docs] def plot_wavelengths_vs_potential( self, measurement=None, wavelengths=None, axes=None, cmap_name="jet", tspan=None, **kwargs, ): """Plot the dO.D. for specific wavelength in the top panel vs potential Args: measurement (Measurement): The measurement to be plotted, if different from self.measurement wavelengths (list of str): The names of the wavelengths to track as strings, e.g. "w400" for 400 nm axes (list of Ax): The axes to plot on, defaults to new matplotlib axes cmap_name (str): Name of the colormap. Defaults to "jet" tspan (timespan): The timespan to plot **kwargs: Additional key-word arguments are passed on to ECPlotter.plot_vs_potential """ measurement = measurement or self.measurement wavelengths = wavelengths or measurement.tracked_wavelengths cmap = mpl.cm.get_cmap(cmap_name) norm = mpl.colors.Normalize(vmin=min(measurement.wl), vmax=max(measurement.wl)) if not axes: axes = self.new_two_panel_axes() for wl_str in wavelengths: x = float(wl_str[1:]) try: t, y = measurement.grab(wl_str, tspan=tspan) except SeriesNotFoundError: measurement.track_wavelength(x) t, y = measurement.grab(wl_str, tspan=tspan) v = measurement.v axes[0].plot(v, y, color=cmap(norm(x)), label=wl_str) axes[0].legend() axes[0].set_ylabel("$\Delta$O.D.") self.ec_plotter.plot_vs_potential( measurement=measurement, ax=axes[1], tspan=tspan, **kwargs )