latools/helpers/plot.py
def tplot(self, analytes=None, figsize=[10, 4], scale='log', filt=None,
              ranges=False, stats=False, stat='nanmean', err='nanstd',
              focus_stage=None, err_envelope=False, ax=None):
        """
        Plot analytes as a function of Time.

        Parameters
        ----------
        analytes : array_like
            list of strings containing names of analytes to plot.
            None = all analytes.
        figsize : tuple
            size of final figure.
        scale : str or None
           'log' = plot data on log scale
        filt : bool, str or dict
            False: plot unfiltered data.
            True: plot filtered data over unfiltered data.
            str: apply filter key to all analytes
            dict: apply key to each analyte in dict. Must contain all
            analytes plotted. Can use self.filt.keydict.
        ranges : bool
            show signal/background regions.
        stats : bool
            plot average and error of each trace, as specified by `stat` and
            `err`.
        stat : str
            average statistic to plot.
        err : str
            error statistic to plot.

        Returns
        -------
        figure, axis
        """
        if type(analytes) is str:
            analytes = [analytes]
        if analytes is None:
            analytes = self.analytes

        if focus_stage is None:
            focus_stage = self.focus_stage
        
        # exclude internal standard from analytes
        if focus_stage in ['ratios', 'calibrated']:
            analytes = [a for a in analytes if a != self.internal_standard]

        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_axes([.1, .12, .77, .8])
            ret = True
        else:
            fig = ax.figure
            ret = False

        for a in analytes:
            x = self.Time
            y, yerr = unpack_uncertainties(self.data[focus_stage][a])

            if scale is 'log':
                ax.set_yscale('log')
                y[y == 0] = np.nan

            if filt:
                ind = self.filt.grab_filt(filt, a)
                xf = x.copy()
                yf = y.copy()
                yerrf = yerr.copy()
                if any(~ind):
                    xf[~ind] = np.nan
                    yf[~ind] = np.nan
                    yerrf[~ind] = np.nan
                if any(~ind):
                    ax.plot(x, y, color=self.cmap[a], alpha=.2, lw=0.6)
                ax.plot(xf, yf, color=self.cmap[a], label=a)
                if err_envelope:
                    ax.fill_between(xf, yf - yerrf, yf + yerrf, color=self.cmap[a],
                                    alpha=0.2, zorder=-1)
            else:
                ax.plot(x, y, color=self.cmap[a], label=a)
                if err_envelope:
                    ax.fill_between(x, y - yerr, y + yerr, color=self.cmap[a],
                                    alpha=0.2, zorder=-1)

            # Plot averages and error envelopes
            if stats and hasattr(self, 'stats'):
                warnings.warn('\nStatistic plotting is broken.\nCheck progress here: https://github.com/oscarbranson/latools/issues/18')
                pass
                # sts = self.stats[sig][0].size
                # if sts > 1:
                #     for n in np.arange(self.n):
                #         n_ind = ind & (self.ns == n + 1)
                #         if sum(n_ind) > 2:
                #             x = [self.Time[n_ind][0], self.Time[n_ind][-1]]
                #             y = [self.stats[sig][self.stats['analytes'] == a][0][n]] * 2

                #             yp = ([self.stats[sig][self.stats['analytes'] == a][0][n] +
                #                   self.stats[err][self.stats['analytes'] == a][0][n]] * 2)
                #             yn = ([self.stats[sig][self.stats['analytes'] == a][0][n] -
                #                   self.stats[err][self.stats['analytes'] == a][0][n]] * 2)

                #             ax.plot(x, y, color=self.cmap[a], lw=2)
                #             ax.fill_between(x + x[::-1], yp + yn,
                #                             color=self.cmap[a], alpha=0.4,
                #                             linewidth=0)
                # else:
                #     x = [self.Time[0], self.Time[-1]]
                #     y = [self.stats[sig][self.stats['analytes'] == a][0]] * 2
                #     yp = ([self.stats[sig][self.stats['analytes'] == a][0] +
                #           self.stats[err][self.stats['analytes'] == a][0]] * 2)
                #     yn = ([self.stats[sig][self.stats['analytes'] == a][0] -
                #           self.stats[err][self.stats['analytes'] == a][0]] * 2)

                #     ax.plot(x, y, color=self.cmap[a], lw=2)
                #     ax.fill_between(x + x[::-1], yp + yn, color=self.cmap[a],
                #                     alpha=0.4, linewidth=0)

        if ranges:
            for lims in self.bkgrng:
                ax.axvspan(*lims, color='k', alpha=0.1, zorder=-1)
            for lims in self.sigrng:
                ax.axvspan(*lims, color='r', alpha=0.1, zorder=-1)

        ax.text(0.01, 0.99, self.sample + ' : ' + focus_stage,
                transform=ax.transAxes,
                ha='left', va='top')

        ax.set_xlabel('Time (s)')
        ax.set_xlim(np.nanmin(x), np.nanmax(x))

        # y label
        ud = {'rawdata': 'counts',
              'despiked': 'counts',
              'bkgsub': 'background corrected counts',
              'ratios': 'counts/{:s} count',
              'calibrated': 'mol/mol {:s}'}
        if focus_stage in ['ratios', 'calibrated']:
            ud[focus_stage] = ud[focus_stage].format(self.internal_standard)
        ax.set_ylabel(ud[focus_stage])

        # if interactive:
        #     ax.legend()
        #     plugins.connect(fig, plugins.MousePosition(fontsize=14))
        #     display.clear_output(wait=True)
        #     display.display(fig)
        #     input('Press [Return] when finished.')
        # else:
        ax.legend(bbox_to_anchor=(1.15, 1))

        if ret:
            return fig, ax
def tplot(self, analytes=None, figsize=[10, 4], scale='log', filt=None,
              ranges=False, stats=False, stat='nanmean', err='nanstd',
              focus_stage=None, err_envelope=False, ax=None):
        """
        Plot analytes as a function of Time.

        Parameters
        ----------
        analytes : array_like
            list of strings containing names of analytes to plot.
            None = all analytes.
        figsize : tuple
            size of final figure.
        scale : str or None
           'log' = plot data on log scale
        filt : bool, str or dict
            False: plot unfiltered data.
            True: plot filtered data over unfiltered data.
            str: apply filter key to all analytes
            dict: apply key to each analyte in dict. Must contain all
            analytes plotted. Can use self.filt.keydict.
        ranges : bool
            show signal/background regions.
        stats : bool
            plot average and error of each trace, as specified by `stat` and
            `err`.
        stat : str
            average statistic to plot.
        err : str
            error statistic to plot.

        Returns
        -------
        figure, axis
        """
        if type(analytes) is str:
            analytes = [analytes]
        if analytes is None:
            analytes = self.analytes

        if focus_stage is None:
            focus_stage = self.focus_stage
        
        # exclude internal standard from analytes
        if focus_stage in ['ratios', 'calibrated']:
            analytes = [a for a in analytes if a != self.internal_standard]

        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_axes([.1, .12, .77, .8])
            ret = True
        else:
            fig = ax.figure
            ret = False

        for a in analytes:
            x = self.Time
            y, yerr = unpack_uncertainties(self.data[focus_stage][a])

            if scale is 'log':
                ax.set_yscale('log')
                y[y == 0] = np.nan

            if filt:
                ind = self.filt.grab_filt(filt, a)
                xf = x.copy()
                yf = y.copy()
                yerrf = yerr.copy()
                if any(~ind):
                    xf[~ind] = np.nan
                    yf[~ind] = np.nan
                    yerrf[~ind] = np.nan
                if any(~ind):
                    ax.plot(x, y, color=self.cmap[a], alpha=.2, lw=0.6)
                ax.plot(xf, yf, color=self.cmap[a], label=a)
                if err_envelope:
                    ax.fill_between(xf, yf - yerrf, yf + yerrf, color=self.cmap[a],
                                    alpha=0.2, zorder=-1)
            else:
                ax.plot(x, y, color=self.cmap[a], label=a)
                if err_envelope:
                    ax.fill_between(x, y - yerr, y + yerr, color=self.cmap[a],
                                    alpha=0.2, zorder=-1)

            # Plot averages and error envelopes
            if stats and hasattr(self, 'stats'):
                warnings.warn('\nStatistic plotting is broken.\nCheck progress here: https://github.com/oscarbranson/latools/issues/18')
                pass
                # sts = self.stats[sig][0].size
                # if sts > 1:
                #     for n in np.arange(self.n):
                #         n_ind = ind & (self.ns == n + 1)
                #         if sum(n_ind) > 2:
                #             x = [self.Time[n_ind][0], self.Time[n_ind][-1]]
                #             y = [self.stats[sig][self.stats['analytes'] == a][0][n]] * 2

                #             yp = ([self.stats[sig][self.stats['analytes'] == a][0][n] +
                #                   self.stats[err][self.stats['analytes'] == a][0][n]] * 2)
                #             yn = ([self.stats[sig][self.stats['analytes'] == a][0][n] -
                #                   self.stats[err][self.stats['analytes'] == a][0][n]] * 2)

                #             ax.plot(x, y, color=self.cmap[a], lw=2)
                #             ax.fill_between(x + x[::-1], yp + yn,
                #                             color=self.cmap[a], alpha=0.4,
                #                             linewidth=0)
                # else:
                #     x = [self.Time[0], self.Time[-1]]
                #     y = [self.stats[sig][self.stats['analytes'] == a][0]] * 2
                #     yp = ([self.stats[sig][self.stats['analytes'] == a][0] +
                #           self.stats[err][self.stats['analytes'] == a][0]] * 2)
                #     yn = ([self.stats[sig][self.stats['analytes'] == a][0] -
                #           self.stats[err][self.stats['analytes'] == a][0]] * 2)

                #     ax.plot(x, y, color=self.cmap[a], lw=2)
                #     ax.fill_between(x + x[::-1], yp + yn, color=self.cmap[a],
                #                     alpha=0.4, linewidth=0)

        if ranges:
            for lims in self.bkgrng:
                ax.axvspan(*lims, color='k', alpha=0.1, zorder=-1)
            for lims in self.sigrng:
                ax.axvspan(*lims, color='r', alpha=0.1, zorder=-1)

        ax.text(0.01, 0.99, self.sample + ' : ' + focus_stage,
                transform=ax.transAxes,
                ha='left', va='top')

        ax.set_xlabel('Time (s)')
        ax.set_xlim(np.nanmin(x), np.nanmax(x))

        # y label
        ud = {'rawdata': 'counts',
              'despiked': 'counts',
              'bkgsub': 'background corrected counts',
              'ratios': 'counts/{:s} count',
              'calibrated': 'mol/mol {:s}'}
        if focus_stage in ['ratios', 'calibrated']:
            ud[focus_stage] = ud[focus_stage].format(self.internal_standard)
        ax.set_ylabel(ud[focus_stage])

        # if interactive:
        #     ax.legend()
        #     plugins.connect(fig, plugins.MousePosition(fontsize=14))
        #     display.clear_output(wait=True)
        #     display.display(fig)
        #     input('Press [Return] when finished.')
        # else:
        ax.legend(bbox_to_anchor=(1.15, 1))

        if ret:
            return fig, ax
Plot analytes as a function of Time.

        Parameters
        ----------
        analytes : array_like
            list of strings containing names of analytes to plot.
            None = all analytes.
        figsize : tuple
            size of final figure.
        scale : str or None
           'log' = plot data on log scale
        filt : bool, str or dict
            False: plot unfiltered data.
            True: plot filtered data over unfiltered data.
            str: apply filter key to all analytes
            dict: apply key to each analyte in dict. Must contain all
            analytes plotted. Can use self.filt.keydict.
        ranges : bool
            show signal/background regions.
        stats : bool
            plot average and error of each trace, as specified by `stat` and
            `err`.
        stat : str
            average statistic to plot.
        err : str
            error statistic to plot.

        Returns
        -------
        figure, axis