Repository: wright-group/WrightTools

Issue:
remove unusued artists

`artists.Absorbance._smooth` parameters

https://github.com/wright-group/WrightTools/blob/1bdc81d0aa4f68f3172b872b393f74182ceadc8c/WrightTools/artists.py#L2313

Currently accepts a `window_type` parameter which does nothing

We may wish to drop this method entirely in favour of kit.smooth, slicing the arrays where it is called


Discussion:

Docstring should be updated to proper style, fitting the changes made

Resolving patch:
diff --git a/WrightTools/artists/_absorbance.py b/WrightTools/artists/_absorbance.py
deleted file mode 100644
--- a/WrightTools/artists/_absorbance.py
+++ /dev/null
@@ -1,140 +0,0 @@
-"""Tools for visualizing data."""
-
-
-# --- import --------------------------------------------------------------------------------------
-
-
-import numpy as np
-
-import matplotlib.pyplot as plt
-
-from .. import kit as wt_kit
-from ._base import create_figure
-
-# --- classes -------------------------------------------------------------------------------------
-
-
-class Absorbance:
-    """Absorbance plot."""
-
-    def __init__(self, data):
-        """Absorbance plot.
-
-        Parameters
-        ----------
-        data : WrightTools.data.Data object, or list thereof
-           Absorbance data to plot.
-        """
-        raise NotImplementedError
-        if not isinstance(data, list):
-            data = [data]
-        self.data = data
-
-    def plot(
-        self, channel_index=0, xlim=None, ylim=None, yticks=True, derivative=True, n_smooth=10
-    ):
-        """Plot.
-
-        Parameters
-        ----------
-        channel_index : int (optional)
-            Channel index. Default is 0.
-        xlim : [xmin, xmax] (optional)
-            Energy axis limits. Default is None (inherits from data).
-        ylim : [ymin, ymax] (optional)
-            Absorption axis limits. Default is None (inherits from data).
-        yticks : boolean (optional)
-            Toggle yticks. Default is True.
-        derivative : boolean (optional)
-            Toggle plotting derivative. Default is True.
-        n_smooth : integer (optioanl)
-            Smoothing factor. Default is 10.
-        """
-        # prepare plot environment ----------------------------------------------------------------
-        self.font_size = 14
-        if derivative:
-            aspects = [[[0, 0], 0.35], [[1, 0], 0.35]]
-            hspace = 0.1
-            fig, gs = create_figure(
-                width="single", cols=[1], hspace=hspace, nrows=2, aspects=aspects
-            )
-            self.ax1 = plt.subplot(gs[0])
-            plt.ylabel("OD", fontsize=18)
-            plt.grid()
-            plt.setp(self.ax1.get_xticklabels(), visible=False)
-            self.ax2 = plt.subplot(gs[1], sharex=self.ax1)
-            plt.grid()
-            plt.ylabel("2nd der.", fontsize=18)
-        else:
-            aspects = [[[0, 0], 0.35]]
-            fig, gs = create_figure(width="single", cols=[1], aspects=aspects)
-            self.ax1 = plt.subplot(111)
-            plt.ylabel("OD", fontsize=18)
-            plt.grid()
-        plt.xticks(rotation=45)
-        for data in self.data:
-            # import data -------------------------------------------------------------------------
-            xi = data.axes[0][:]
-            zi = data.channels[channel_index][:]
-            # scale -------------------------------------------------------------------------------
-            if xlim:
-                plt.xlim(xlim[0], xlim[1])
-                min_index = np.argmin(abs(xi - min(xlim)))
-                max_index = np.argmin(abs(xi - max(xlim)))
-                zi_truncated = zi[min(min_index, max_index) : max(min_index, max_index)]
-                zi -= zi_truncated.min()
-                zi_truncated = zi[min(min_index, max_index) : max(min_index, max_index)]
-                zi /= zi_truncated.max()
-            else:
-                xlim = xi.min(), xi.max()
-            # plot absorbance ---------------------------------------------------------------------
-            self.ax1.plot(xi, zi, lw=2)
-            self.ax1.set_xlim(*xlim)
-            # now plot 2nd derivative -------------------------------------------------------------
-            if derivative:
-                # compute second derivative
-                xi2, zi2 = self._smooth(np.array([xi, zi]), n_smooth)
-                diff = wt_kit.diff(xi2, zi2, order=2)
-                # plot the data!
-                self.ax2.plot(xi2, diff, lw=2)
-                self.ax2.grid(b=True)
-                plt.xlabel(data.axes[0].get_label(), fontsize=18)
-        # ticks -----------------------------------------------------------------------------------
-        if not yticks:
-            self.ax1.get_yaxis().set_ticks([])
-        if derivative:
-            self.ax2.get_yaxis().set_ticks([])
-            self.ax2.axhline(0, color="k", ls=":")
-        # title -----------------------------------------------------------------------------------
-        if len(self.data) == 1:  # only attempt this if we are plotting one data object
-            title_text = self.data[0].name
-            plt.suptitle(title_text, fontsize=self.font_size)
-        # finish ----------------------------------------------------------------------------------
-        if xlim:
-            plt.xlim(xlim[0], xlim[1])
-            for axis, xi, zi in [[self.ax1, xi, zi], [self.ax2, xi2, diff]]:
-                min_index = np.argmin(abs(xi - min(xlim)))
-                max_index = np.argmin(abs(xi - max(xlim)))
-                zi_truncated = zi[min_index:max_index]
-                extra = (zi_truncated.max() - zi_truncated.min()) * 0.1
-                axis.set_ylim(zi_truncated.min() - extra, zi_truncated.max() + extra)
-        if ylim:
-            self.ax1.set_ylim(ylim)
-
-    def _smooth(self, dat1, n=20, window_type="default"):
-        """Smooth to prevent 2nd derivative from being too noisy.
-
-        Parameters
-        ----------
-        dat1 : 2D array
-            [xlis,ylis]
-        n : integer
-            Smoothing amount.
-        window_type : string
-            Does literally nothing.
-        """
-        for i in range(n, len(dat1[1]) - n):
-            # change the x value to the average
-            window = dat1[1][i - n : i + n].copy()
-            dat1[1][i] = window.mean()
-        return dat1[:][:, n:-n]
diff --git a/WrightTools/artists/_diff2d.py b/WrightTools/artists/_diff2d.py
deleted file mode 100644
--- a/WrightTools/artists/_diff2d.py
+++ /dev/null
@@ -1,224 +0,0 @@
-"""Diff2D."""
-# --- import --------------------------------------------------------------------------------------
-
-import collections
-import os
-
-import numpy as np
-
-import matplotlib.pyplot as plt
-import matplotlib.gridspec as grd
-
-from ..WrightTools import kit as wt_kit
-from ._base import pcolor_helper, get_constant_text
-from ._colors import colormaps
-
-
-class Diff2D:
-    """Diff2D."""
-
-    def __init__(self, minuend, subtrahend, xaxis=1, yaxis=0, at={}, verbose=True):
-        """Plot the difference between exactly two datasets in 2D.
-
-        both data objects must have the same axes with the same name
-        axes do not need to be in the same order or have the same points
-        """
-        self.minuend = minuend.copy()
-        self.subtrahend = subtrahend.copy()
-        # check if axes are valid - same axis names in both data objects
-        minuend_counter = collections.Counter(self.minuend.axis_names)
-        subrahend_counter = collections.Counter(self.subtrahend.axis_names)
-        if minuend_counter == subrahend_counter:
-            pass
-        else:
-            print("axes are not equivalent - difference_2D cannot initialize")
-            print("  minuhend axes -", self.minuend.axis_names)
-            print("  subtrahend axes -", self.subtrahend.axis_names)
-            raise RuntimeError("axes incompataible")
-        # transpose subrahend to agree with minuend
-        transpose_order = [
-            self.minuend.axis_names.index(name) for name in self.subtrahend.axis_names
-        ]
-        self.subtrahend.transpose(transpose_order, verbose=False)
-        # map subtrahend axes onto minuend axes
-        for i in range(len(self.minuend.axes)):
-            self.subtrahend.axes[i].convert(self.minuend.axes[i].units)
-            self.subtrahend.map_axis(i, self.minuend.axes[i][:])
-        # chop
-        self.minuend_chopped = self.minuend.chop(yaxis, xaxis, at=at, verbose=False)
-        self.subtrahend_chopped = self.subtrahend.chop(yaxis, xaxis, at=at, verbose=False)
-        if verbose:
-            print("difference_2D recieved data to make %d plots" % len(self.minuend_chopped))
-        # defaults
-        self.font_size = 18
-
-    def plot(
-        self,
-        channel_index=0,
-        contours=9,
-        pixelated=True,
-        cmap="default",
-        facecolor="grey",
-        dynamic_range=False,
-        local=False,
-        contours_local=True,
-        xlim=None,
-        ylim=None,
-        autosave=False,
-        save_directory=None,
-        fname=None,
-        verbose=True,
-    ):
-        """Set contours to zero to turn off.
-
-        dynamic_range forces the colorbar to use all of its colors (only matters
-        for signed data)
-        """
-        # TODO: add parameters to this plot function (KS)
-        fig = None
-        if len(self.minuend_chopped) > 10:
-            if not autosave:
-                print("too many images will be generated: forcing autosave")
-                autosave = True
-        # prepare output folder
-        if autosave:
-            plt.ioff()
-            if save_directory:
-                pass
-            else:
-                if len(self.minuend_chopped) == 1:
-                    save_directory = os.getcwd()
-                    if fname:
-                        pass
-                    else:
-                        fname = self.minuend.name
-                else:
-                    folder_name = "difference_2D " + wt_kit.get_timestamp()
-                    os.mkdir(folder_name)
-                    save_directory = folder_name
-        # chew through image generation
-        for i in range(len(self.minuend_chopped)):
-            # create figure -----------------------------------------------------------------------
-            if fig:
-                plt.close(fig)
-            fig = plt.figure(figsize=(22, 7))
-            gs = grd.GridSpec(1, 6, width_ratios=[20, 20, 1, 1, 20, 1], wspace=0.1)
-            subplot_main = plt.subplot(gs[0])
-            subplot_main.patch.set_facecolor(facecolor)
-            # levels ------------------------------------------------------------------------------
-            levels = np.linspace(0, 1, 200)
-            # main plot ---------------------------------------------------------------------------
-            # get colormap
-            mycm = colormaps[cmap]
-            mycm.set_bad(facecolor)
-            mycm.set_under(facecolor)
-            for j in range(2):
-                if j == 0:
-                    current_chop = self.minuend_chopped[i]
-                elif j == 1:
-                    current_chop = self.subtrahend_chopped[i]
-                axes = current_chop.axes
-                channels = current_chop.channels
-                constants = current_chop.constants
-                xaxis = axes[1]
-                yaxis = axes[0]
-                channel = channels[channel_index]
-                zi = channel[:]
-                plt.subplot(gs[j])
-                # fill in main data environment
-                if pixelated:
-                    xi, yi, zi = pcolor_helper(xaxis[:], yaxis[:], zi)
-                    cax = plt.pcolormesh(
-                        xi, yi, zi, cmap=mycm, vmin=levels.min(), vmax=levels.max()
-                    )
-                    plt.xlim(xaxis.min(), xaxis.max())
-                    plt.ylim(yaxis.min(), yaxis.max())
-                else:
-                    cax = subplot_main.contourf(xaxis[:], yaxis[:], zi, levels, cmap=mycm)
-                plt.xticks(rotation=45)
-                # grid ----------------------------------------------------------------------------
-                plt.grid(b=True)
-                if xaxis.units == yaxis.units:
-                    # add diagonal line
-                    if xlim:
-                        x = xlim
-                    else:
-                        x = xaxis[:]
-                    if ylim:
-                        y = ylim
-                    else:
-                        y = yaxis[:]
-
-                    diag_min = max(min(x), min(y))
-                    diag_max = min(max(x), max(y))
-                    plt.plot([diag_min, diag_max], [diag_min, diag_max], "k:")
-                # contour lines -------------------------------------------------------------------
-                if contours:
-                    if contours_local:
-                        # force top and bottom contour to be just outside of data range
-                        # add two contours
-                        contours_levels = np.linspace(
-                            channel.null() - 1e-10, np.nanmax(zi) + 1e-10, contours + 2
-                        )
-                    else:
-                        contours_levels = contours
-                    plt.contour(xaxis[:], yaxis[:], zi, contours_levels, colors="k")
-                # finish main subplot -------------------------------------------------------------
-                if xlim:
-                    subplot_main.set_xlim(xlim[0], xlim[1])
-                else:
-                    subplot_main.set_xlim(xaxis[:][0], xaxis[:][-1])
-                if ylim:
-                    subplot_main.set_ylim(ylim[0], ylim[1])
-                else:
-                    subplot_main.set_ylim(yaxis[:][0], yaxis[:][-1])
-            # colorbar ----------------------------------------------------------------------------
-            subplot_cb = plt.subplot(gs[2])
-            cbar_ticks = np.linspace(levels.min(), levels.max(), 11)
-            plt.colorbar(cax, cax=subplot_cb, ticks=cbar_ticks)
-            # difference --------------------------------------------------------------------------
-            # get colormap
-            mycm = colormaps["seismic"]
-            mycm.set_bad(facecolor)
-            mycm.set_under(facecolor)
-            dzi = (
-                self.minuend_chopped[i].channels[0][:] - self.subtrahend_chopped[i].channels[0][:]
-            )
-            dax = plt.subplot(gs[4])
-            plt.subplot(dax)
-            X, Y, Z = pcolor_helper(xaxis[:], yaxis[:], dzi)
-            largest = np.nanmax(np.abs(dzi))
-            dcax = dax.pcolor(X, Y, Z, vmin=-largest, vmax=largest, cmap=mycm)
-            dax.set_xlim(xaxis.min(), xaxis.max())
-            dax.set_ylim(yaxis.min(), yaxis.max())
-            differenc_cb = plt.subplot(gs[5])
-            dcbar = plt.colorbar(dcax, cax=differenc_cb)
-            dcbar.set_label(
-                self.minuend.channels[channel_index].name
-                + " - "
-                + self.subtrahend.channels[channel_index].name
-            )
-            # title -------------------------------------------------------------------------------
-            title_text = self.minuend.name + " - " + self.subtrahend.name
-            constants_text = "\n" + get_constant_text(constants)
-            plt.suptitle(title_text + constants_text, fontsize=self.font_size)
-            plt.figtext(0.03, 0.5, yaxis.get_label(), fontsize=self.font_size, rotation=90)
-            plt.figtext(
-                0.5, 0.01, xaxis.get_label(), fontsize=self.font_size, horizontalalignment="center"
-            )
-            # cleanup -----------------------------------------------------------------------------
-            fig.subplots_adjust(left=0.075, right=1 - 0.075, top=0.90, bottom=0.15)
-            plt.setp(plt.subplot(gs[1]).get_yticklabels(), visible=False)
-            plt.setp(plt.subplot(gs[4]).get_yticklabels(), visible=False)
-            # save figure -------------------------------------------------------------------------
-            if autosave:
-                if fname:
-                    file_name = fname + " " + str(i).zfill(3)
-                else:
-                    file_name = str(i).zfill(3)
-                fpath = os.path.join(save_directory, file_name + ".png")
-                plt.savefig(fpath, facecolor="none")
-                plt.close()
-                if verbose:
-                    print("image saved at", fpath)
-        plt.ion()
diff --git a/WrightTools/artists/_pdf2dslices.py b/WrightTools/artists/_pdf2dslices.py
deleted file mode 100644
--- a/WrightTools/artists/_pdf2dslices.py
+++ /dev/null
@@ -1,283 +0,0 @@
-"""PDF 2D slices."""
-# --- import --------------------------------------------------------------------------------------
-
-import datetime
-import os
-
-import numpy as np
-
-import matplotlib.pyplot as plt
-from matplotlib.backends.backend_pdf import PdfPages
-
-from . import _title, add_sideplot, create_figure, colormaps, pcolor_helper
-from ._base import get_constant_text, diagonal_line
-
-
-class PDF2DSlices:
-    """PDF 2D slices."""
-
-    def __init__(self, datas, name="", data_signed=False):
-        """Initialize the 2D slice PDF generator.
-
-        Parameters
-        ----------
-        datas : list of WrightTools.data.Data objects
-            Datas to plot.
-        name : string (optional)
-            Name. Default is ''.
-        data_signed : boolean (optional)
-            Toggle data signed. Default is False.
-        """
-        self.datas = datas
-        self.name = name
-
-        self.sideplot_dictionary = {n: [] for n in self.datas[0].axis_names}
-        self.data_signed = data_signed
-        if self.data_signed:
-            self.sideplot_limits = [-1.1, 1.1]
-            self.cmap = colormaps["seismic"]
-        else:
-            self.sideplot_limits = [0, 1.1]
-            self.cmap = colormaps["default"]
-
-    def _fill_plot(self, xaxis, yaxis, zi, ax, cax, title, yticks, vmin=None, vmax=None):
-        xi = xaxis[:]
-        yi = yaxis[:]
-        X, Y, Z = pcolor_helper(xi, yi, zi)
-        if vmax is None:
-            vmax = np.nanmax(Z)
-        if vmin is None:
-            vmin = np.nanmin(Z)
-        if self.data_signed:
-            extent = max(vmax, -vmin)
-            vmin = -extent
-            vmax = extent
-        # pcolor
-        mappable = ax.pcolor(X, Y, Z, cmap=self.cmap, vmin=vmin, vmax=vmax)
-        ax.set_xlim(xi.min(), xi.max())
-        ax.set_ylim(yi.min(), yi.max())
-        ax.grid()
-        if xaxis.units_kind == yaxis.units_kind:
-            diagonal_line(xi, yi, ax=ax)
-        plt.setp(ax.get_yticklabels(), visible=yticks)
-        # x sideplot
-        sp = add_sideplot(ax, "x")
-        b = np.nansum(zi, axis=0) * len(yaxis[:])
-        b[b == 0] = np.nan
-        b /= np.nanmax(b)
-        sp.plot(xi, b, lw=2, c="b")
-        sp.set_xlim([xi.min(), xi.max()])
-        sp.set_ylim(self.sideplot_limits)
-        for data, channel_index, c in self.sideplot_dictionary[xaxis.name]:
-            data.convert(xaxis.units, verbose=False)
-            sp_xi = data.axes[0][:]
-            sp_zi = data.channels[channel_index][:]
-            sp_zi[sp_xi < xi.min()] = 0
-            sp_zi[sp_xi > xi.max()] = 0
-            sp_zi /= np.nanmax(sp_zi)
-            sp.plot(sp_xi, sp_zi, lw=2, c=c)
-        sp.grid()
-        if self.data_signed:
-            sp.axhline(0, c="k", lw=1)
-        sp.set_title(title, fontsize=18)
-        sp0 = sp
-        # y sideplot
-        sp = add_sideplot(ax, "y")
-        b = np.nansum(zi, axis=1) * len(xaxis[:])
-        b[b == 0] = np.nan
-        b /= np.nanmax(b)
-        sp.plot(b, yi, lw=2, c="b")
-        sp.set_xlim(self.sideplot_limits)
-        sp.set_ylim([yi.min(), yi.max()])
-        for data, channel_index, c in self.sideplot_dictionary[yaxis.name]:
-            data.convert(xaxis.units, verbose=False)
-            sp_xi = data.axes[0][:]
-            sp_zi = data.channels[channel_index][:]
-            sp_zi[sp_xi < xi.min()] = 0
-            sp_zi[sp_xi > xi.max()] = 0
-            sp_zi /= np.nanmax(sp_zi)
-            sp.plot(sp_zi, sp_xi, lw=2, c=c)
-        sp.grid()
-        if self.data_signed:
-            sp.axvline(0, c="k", lw=1)
-        sp1 = sp
-        # colorbar
-        plt.colorbar(mappable=mappable, cax=cax)
-        return [sp0, sp1]
-
-    def _fill_row(self, data, channel_index, gs, row_index, global_limits):
-        xaxis = data.axes[1]
-        yaxis = data.axes[0]
-        vmin, vmax = global_limits
-        # local
-        ax0 = plt.subplot(gs[row_index, 0])
-        cax = plt.subplot(gs[row_index, 1])
-        zi = data.channels[channel_index][:]
-        kwargs = {}
-        if not self.data_signed:
-            kwargs["vmin"] = vmin
-        sps0 = self._fill_plot(
-            xaxis, yaxis, zi, ax0, cax, title=data.name + " local", yticks=True, **kwargs
-        )
-        # global
-        ax1 = plt.subplot(gs[row_index, 3])
-        cax = plt.subplot(gs[row_index, 4])
-        zi = data.channels[channel_index][:]
-        sps1 = self._fill_plot(
-            xaxis,
-            yaxis,
-            zi,
-            ax1,
-            cax,
-            title=data.name + " global",
-            vmin=vmin,
-            vmax=vmax,
-            yticks=False,
-        )
-        return [[ax0, ax1], [sps0, sps1]]
-
-    def _label_slide(self, pdf, text):
-        cols = [1, "cbar", 0.25, 1, "cbar"]
-        fig, gs = create_figure(width="double", nrows=len(self.datas), cols=cols, hspace=0.5)
-        fig.text(0.5, 0.5, text, fontsize=40, ha="center", va="center")
-        pdf.savefig()
-        plt.close(fig)
-
-    def sideplot(self, data, c, axes, channel=0):
-        """Add sideplot."""
-        # get channel index
-        if type(channel) in [int, float]:
-            channel_index = int(channel)
-        elif isinstance(channel, str):
-            channel_index = self.datas[0].channel_names.index(channel)
-        else:
-            print("channel type not recognized in mpl_2D!")
-        # add to sideplot_dictionary
-        for axis_name in axes:
-            self.sideplot_dictionary[axis_name].append([data, channel_index, c])
-
-    def plot(self, channel=0, output_path=None, w1w2=True, w1_wigner=True, w2_wigner=True):
-        """Plot."""
-        # get channel index
-        if type(channel) in [int, float]:
-            channel_index = int(channel)
-        elif isinstance(channel, str):
-            channel_index = self.datas[0].channel_names.index(channel)
-        else:
-            print("channel type not recognized in mpl_2D!")
-        # create pdf
-        with PdfPages(output_path) as pdf:
-            if w1w2:
-                # 2D Frequencies
-                self.chopped_datas = [d.chop("w2", "wmw1") for d in self.datas]  # y, x
-                self._label_slide(pdf, "2D frequencies")
-                for slice_index in range(len(self.chopped_datas[0])):  # for each chop...
-                    print("2D frequency", slice_index)
-                    cols = [1, "cbar", 0.25, 1, "cbar"]
-                    fig, gs = create_figure(
-                        width="double", nrows=len(self.datas), cols=cols, hspace=0.5
-                    )
-                    for data_index in range(len(self.datas)):
-                        data = self.chopped_datas[data_index][slice_index]
-                        if self.data_signed:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].min(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        else:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].null(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        axs, spss = self._fill_row(
-                            data, channel_index, gs, data_index, global_limits
-                        )
-                        if not data_index == len(self.datas) - 1:
-                            for ax in axs:
-                                plt.setp(ax.get_xticklabels(), visible=False)
-                    constant_text = get_constant_text(data.constants)
-                    _title(fig, self.name, constant_text)
-                    pdf.savefig()
-                    plt.close(fig)
-            if w1_wigner:
-                # w1 Wigners
-                self.chopped_datas = [d.chop("d2", "wmw1") for d in self.datas]  # y, x
-                self._label_slide(pdf, "w1 wigners")
-                for slice_index in range(len(self.chopped_datas[0])):  # for each chop...
-                    print("w1 wigner", slice_index)
-                    cols = [1, "cbar", 0.25, 1, "cbar"]
-                    fig, gs = create_figure(
-                        width="double", nrows=len(self.datas), cols=cols, hspace=0.5
-                    )
-                    for data_index in range(len(self.datas)):
-                        data = self.chopped_datas[data_index][slice_index]
-                        if self.data_signed:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].min(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        else:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].null(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        axs, spss = self._fill_row(
-                            data, channel_index, gs, data_index, global_limits
-                        )
-                        if not data_index == len(self.datas) - 1:
-                            for ax in axs:
-                                plt.setp(ax.get_xticklabels(), visible=False)
-                        for ax, sps in zip(axs, spss):
-                            ax.axhline(0, c="k", lw=4)
-                            sps[1].axhline(0, c="k", lw=4)
-                            ax.axvline(data.constants[0][:], c="k", alpha=0.5, lw=4)
-                            sps[0].axvline(data.constants[0][:], c="k", alpha=0.5, lw=4)
-                    constant_text = get_constant_text(data.constants)
-                    _title(fig, self.name, constant_text)
-                    pdf.savefig()
-                    plt.close(fig)
-            if w2_wigner:
-                # w2 Wigners
-                self.chopped_datas = [d.chop("d2", "w2") for d in self.datas]  # y, x
-                self._label_slide(pdf, "w2 wigners")
-                for slice_index in range(len(self.chopped_datas[0])):  # for each chop...
-                    print("w2 wigner", slice_index)
-                    cols = [1, "cbar", 0.25, 1, "cbar"]
-                    fig, gs = create_figure(
-                        width="double", nrows=len(self.datas), cols=cols, hspace=0.5
-                    )
-                    for data_index in range(len(self.datas)):
-                        data = self.chopped_datas[data_index][slice_index]
-                        if self.data_signed:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].min(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        else:
-                            global_limits = [
-                                self.datas[data_index].channels[channel_index].null(),
-                                self.datas[data_index].channels[channel_index].max(),
-                            ]
-                        axs, spss = self._fill_row(
-                            data, channel_index, gs, data_index, global_limits
-                        )
-                        if not data_index == len(self.datas) - 1:
-                            for ax in axs:
-                                plt.setp(ax.get_xticklabels(), visible=False)
-                        for ax, sps in zip(axs, spss):
-                            ax.axhline(0, c="k", lw=4)
-                            sps[1].axhline(0, c="k", lw=4)
-                            ax.axvline(data.constants[0][:], c="k", alpha=0.5, lw=4)
-                            sps[0].axvline(data.constants[0][:], c="k", alpha=0.5, lw=4)
-                    constant_text = get_constant_text(data.constants)
-                    _title(fig, self.name, constant_text)
-                    pdf.savefig()
-                    plt.close(fig)
-            # pdf metadata
-            d = pdf.infodict()
-            d["Title"] = os.path.basename(output_path)
-            d["Author"] = u"WrightTools\xe4nen"
-            d["Subject"] = "CMDS data"
-            d["Keywords"] = ""
-            d["CreationDate"] = datetime.datetime.today()
-            d["ModDate"] = datetime.datetime.today()


Test patch: