예제 #1
0
    def view(self, declevel: int = 0, **kwargs) -> Figure:
        """Produces a 2-D plot with all the masked windows along the bottom for a decimation level
        
        Parameters
        ----------
        declevel : int, optional
            The decimation level. Default is 0.
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts            
        """
        from resistics.common.plot import getViewFonts

        fig: plt.figure = (plt.figure(kwargs["fig"].number) if "fig" in kwargs
                           else plt.figure(figsize=(10, 10)))
        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()

        evalFreq = self.evalFreq[declevel]
        numFreq = len(evalFreq)
        freqIndex = range(0, numFreq)
        levelMasked: Set = set()
        numMasked: List[int] = list()
        freqLabel: List[str] = list()
        for eFreq in evalFreq:
            levelMasked.update(self.maskWindows[eFreq])
            numMasked.append(len(self.maskWindows[eFreq]))
            freqLabel.append("{:.5f}".format(eFreq))

        numMaskedTotal = len(levelMasked)
        levelMasked = np.array(sorted(list(levelMasked)))
        global2localMap = {}
        for idx in range(0, levelMasked.size):
            global2localMap[levelMasked[idx]] = idx
        # make array
        data = np.zeros(shape=(levelMasked.size, numFreq), dtype=int)
        for idx, eFreq in enumerate(evalFreq):
            for gI in self.maskWindows[eFreq]:
                lI = global2localMap[gI]
                data[lI, idx] = idx + 1

        st = fig.suptitle(
            "Masked windows for decimation level: {}".format(declevel),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        # now plot
        ax = plt.subplot(2, 1, 1)
        cmap = cm.get_cmap("Paired", numFreq)
        cmap.set_under("white")
        plt.pcolor(np.transpose(data), cmap=cmap, vmin=1, vmax=numFreq + 1)
        ax.set_yticks(np.array(freqIndex) + 0.5)
        ax.set_yticklabels(freqLabel)
        plt.ylabel("Masked windows for decimation level",
                   fontsize=plotfonts["axisLabel"])
        plt.ylabel("Evaluation Frequency [Hz]",
                   fontsize=plotfonts["axisLabel"])
        plt.title(
            "Relative masked windows for decimation level {}".format(declevel),
            fontsize=plotfonts["title"],
        )
        # set tick sizes
        for label in ax.get_xticklabels() + ax.get_yticklabels():
            label.set_fontsize(plotfonts["axisTicks"])
        # colourbar
        cb = plt.colorbar()
        cb.ax.set_title("Masked\nwindows")
        cb.set_ticks(np.arange(1, numFreq + 1) + 0.5)
        cb.set_ticklabels(freqLabel)

        # bar graph
        ax = plt.subplot(2, 1, 2)
        # add the total number masked
        freqIndex = range(0, numFreq + 1)
        numMasked.append(numMaskedTotal)
        freqLabel.append("Total masked for\n decimation level")
        plt.bar(freqIndex, numMasked)
        ax.set_xticks(freqIndex)
        ax.set_xticklabels(freqLabel)
        plt.xlabel("Evaluation Frequency [Hz]",
                   fontsize=plotfonts["axisLabel"])
        plt.ylabel("Number of masked windows", fontsize=plotfonts["axisLabel"])
        plt.title(
            "Number of masked windows per evaluation frequency",
            fontsize=plotfonts["title"],
        )
        # set tick sizes
        for label in ax.get_xticklabels() + ax.get_yticklabels():
            label.set_fontsize(plotfonts["axisTicks"])

        fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
        plt.show()

        return fig
예제 #2
0
    def view(self, **kwargs) -> Figure:
        """Plot of the calibration function

        Parameters
        ----------
        staticgain : bool, optional
            Boolean flag for having static gain on, default is True
        degrees : bool, optional
            Plot phase in degreesm default is False
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotFonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        ylim_mag : List, optional
            Limits for the magnitude y axis
        ylim_phase : List, optional
            Limits for the phase y axis
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object            
        """
        from resistics.common.plot import getViewFonts

        if "fig" in kwargs:
            fig = plt.figure(kwargs["fig"].number)
        else:
            fig = plt.figure(figsize=(8, 8))
        plotFonts = kwargs[
            "plotFonts"] if "plotFonts" in kwargs else getViewFonts()

        # static gain
        magnitude = self.magnitude
        if "staticgain" in kwargs and not kwargs["staticgain"]:
            magnitude = magnitude / self.staticGain
        # phase
        phaseUnit = self.phaseUnit
        phase = self.phase
        if "degrees" in kwargs and kwargs["degrees"]:
            phaseUnit = "degrees"
            phase = self.phase * (180 / np.pi)

        # plot magnitude
        plt.subplot(2, 1, 1)
        plt.title("Impulse response magnitude", fontsize=plotFonts["title"])
        lab = kwargs["label"] if "label" in kwargs else self.filename
        plt.loglog(self.freqs, magnitude, label=lab)
        if "xlim" in kwargs:
            plt.xlim(kwargs["xlim"])
        if "ylim_mag" in kwargs:
            plt.ylim(kwargs["ylim_mag"])
        plt.xlabel("Frequency [Hz]")
        plt.ylabel("Magnitude [{}]".format(self.magnitudeUnit))
        plt.grid(True)
        # legend
        if "legend" in kwargs and kwargs["legend"]:
            plt.legend(loc=2)

        # plot phase
        plt.subplot(2, 1, 2)
        plt.title("Impulse response phase", fontsize=plotFonts["title"])
        lab = kwargs["label"] if "label" in kwargs else self.filename
        plt.semilogx(self.freqs, phase, label=lab)
        if "xlim" in kwargs:
            plt.xlim(kwargs["xlim"])
        if "ylim_phase" in kwargs:
            plt.ylim(kwargs["ylim_phase"])
        plt.xlabel("Frequency [Hz]")
        plt.ylabel("Phase [{}]".format(phaseUnit))
        plt.grid(True)
        # legend
        if "legend" in kwargs and kwargs["legend"]:
            plt.legend(loc=3)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            plt.tight_layout(rect=[0, 0.02, 1, 0.96])
            plt.show()

        return fig
예제 #3
0
    def view(self, **kwargs) -> Figure:
        """Plot spectra data

        Parameters
        ----------
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        powers : List[List[str]], optional
            A list of cross powers to plot
        xlim : List, optional
            Limits for the x axis
        color : str, rgba Tuple
            The color for the line plot
        legend : bool
            Boolean flag for adding a legend

        Returns
        -------
        plt.figure
            Matplotlib figure object
        """
        freqArray = self.freqArray
        fig = (plt.figure(kwargs["fig"].number)
               if "fig" in kwargs else plt.figure(figsize=(20, 10)))
        plotFonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        color = kwargs["color"] if "color" in kwargs else None
        # suptitle
        st = fig.suptitle("Cross power data", fontsize=plotFonts["suptitle"])
        st.set_y(0.98)
        # plot data
        plotPowers = kwargs["powers"] if "powers" in kwargs else self.powers
        for power in plotPowers:
            plt.plot(
                freqArray,
                np.absolute(self.getPower(power[0], power[1])),
                color=color,
            )
            # x axis options
            plt.xlabel("Frequency [Hz]", fontsize=plotFonts["axisLabel"])
            xlim = kwargs["xlim"] if "xlim" in kwargs else [
                freqArray[0], freqArray[-1]
            ]
            plt.xlim(xlim)
            # y axis options
            plt.ylabel("Cross power amplitude",
                       fontsize=plotFonts["axisLabel"])
            plt.grid()
            # set tick sizes
            ax = plt.gca()
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotFonts["axisTicks"])
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            plt.tight_layout(rect=[0, 0.02, 1, 0.96])
            plt.show()

        return fig
예제 #4
0
    def view(self, **kwargs) -> Figure:
        """View timeseries data as a line plot

        Parameters
        ----------
        sampleStart : int, optional
            Sample to start plotting from
        sampleStop : int, optional
            Sample to plot to                   
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        chans : List[str]
            Channels to plot
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object
        """
        # the number of samples to plot
        sampleStart = 0
        sampleStop = 4096
        if "sampleStart" in kwargs:
            sampleStart = kwargs["sampleStart"]
        if "sampleStop" in kwargs:
            sampleStop = kwargs["sampleStop"]
        if sampleStop >= self.numSamples:
            sampleStop = self.numSamples - 1
        # get the x axis ready
        x = self.getDateArray()
        start = x[sampleStart]
        stop = x[sampleStop]

        # now plot
        fig = (plt.figure(kwargs["fig"].number) if "fig" in kwargs else
               plt.figure(figsize=(20, 2 * self.numChans)))
        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        # suptitle
        st = fig.suptitle(
            "Time data from {} to {}, samples {} to {}".format(
                start, stop, sampleStart, sampleStop),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)
        # now plot the data
        dataChans = kwargs["chans"] if "chans" in kwargs else self.chans
        numDataChans = len(dataChans)
        for idx, chan in enumerate(dataChans):
            ax = plt.subplot(numDataChans, 1, idx + 1)
            plt.title("Channel {}".format(chan), fontsize=plotfonts["title"])

            # check if channel exists in data and if not, leave empty plot so it's clear
            if chan not in self.data:
                continue

            # label for plot
            lab = (kwargs["label"] if "label" in kwargs else
                   "{}: {} to {}".format(chan, start, stop))
            # plot data
            plt.plot(
                x[sampleStart:sampleStop + 1],
                self.data[chan][sampleStart:sampleStop + 1],
                label=lab,
            )
            # add time label
            if idx == numDataChans - 1:
                plt.xlabel("Time", fontsize=plotfonts["axisLabel"])
            # set the xlim
            xlim = kwargs["xlim"] if "xlim" in kwargs else [start, stop]
            plt.xlim(xlim)
            # y axis options
            if isElectric(chan):
                plt.ylabel("mV/km", fontsize=plotfonts["axisLabel"])
            else:
                plt.ylabel("nT or mV", fontsize=plotfonts["axisLabel"])
            plt.grid(True)
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            plt.tight_layout(rect=[0, 0.02, 1, 0.96])
            plt.show()

        return fig
예제 #5
0
    def densityplot(self, eFreqI: int, **kwargs) -> Figure:
        """Plots density plots of statistic components for evaluation frequency index

        Notes
        -----
        By default, the density plots plotted are
        statistic component 1 vs statistic component 2
        statistic component 3 vs statistic component 4
        etc

        But density plots can be explicity set by using the crossplots keyword. They should be specified as a list of a list of strings
        e.g.
        crossplots = [[component2, component3], [component1, component4]]

        Parameters
        ----------
        eFreqI : int
            Evaluation frequency index
        maskwindows : List, np.ndarray
            Global windows to exclude              
        crossplots : List[List[str]], optional
            The parameters to crossplot
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        ylim : List, optional
            Limits for the y axis
        colortitle : str, optional
            Title for the colourbar
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object            
        """
        # deal with maskwindows, which are global indices
        maskWindows = kwargs["maskwindows"] if "maskwindows" in kwargs else []
        plotIndices = self.getUnmaskedIndices(maskWindows)

        # figure out the crossplots
        if "crossplots" in kwargs:
            crossplots = kwargs["crossplots"]
        else:
            crossplots = list(zip(self.winStats[::2], self.winStats[1::2]))

        # plot parameters
        nrows, ncols = self.getRowsCols(self.maxcols, numStats=len(crossplots))
        eFreq = self.evalFreq[eFreqI]

        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        fig = (plt.figure(kwargs["fig"].number) if "fig" in kwargs else
               plt.figure(figsize=(4 * ncols, 5 * nrows)))
        st = fig.suptitle(
            "{} density plots for evaluation frequency: {:.3f} Hz".format(
                self.statName, eFreq),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        # now plot the data
        for idx, cplot in enumerate(crossplots):
            ax = plt.subplot(nrows, ncols, idx + 1)
            plt.title("{} vs. {}".format(cplot[0], cplot[1]),
                      fontsize=plotfonts["title"])
            label = kwargs["label"] if "label" in kwargs else eFreq

            # get plot data
            plotI1 = self.winStats.index(cplot[0])
            plotData1 = np.squeeze(self.stats[:, eFreqI, plotI1])
            plotI2 = self.winStats.index(cplot[1])
            plotData2 = np.squeeze(self.stats[:, eFreqI, plotI2])
            if plotIndices is not None:
                plotData1 = plotData1[plotIndices]
                plotData2 = plotData2[plotIndices]

            nbins = 200
            if "xlim" in kwargs:
                plt.xlim(kwargs["xlim"])
                rangex = kwargs["xlim"]
            else:
                minx = np.percentile(plotData1, 2)
                maxx = np.percentile(plotData1, 98)
                plt.xlim(minx, maxx)
                rangex = [minx, maxx]

            if "ylim" in kwargs:
                plt.ylim(kwargs["ylim"])
                rangey = kwargs["ylim"]
            else:
                miny = np.percentile(plotData2, 2)
                maxy = np.percentile(plotData2, 98)
                plt.ylim(miny, maxy)
                rangey = [miny, maxy]

            plt.hist2d(
                plotData1,
                plotData2,
                bins=(nbins, nbins),
                range=[rangex, rangey],
                cmap=plt.cm.inferno,
            )

            # axis options
            plt.xlabel("Value {}".format(cplot[0]),
                       fontsize=plotfonts["axisLabel"])
            plt.ylabel("Value {}".format(cplot[1]),
                       fontsize=plotfonts["axisLabel"])
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            plt.grid(True, ls="--")
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            fig.tight_layout(rect=[0.02, 0.02, 0.85, 0.92])
            plt.show()

        return fig
예제 #6
0
    def view(self, **kwargs) -> Figure:
        """Plot spectra data

        Parameters
        ----------
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        chans : List[str], optional
            A list of channels to plot
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        color : str, rgba Tuple
            The color for the line plot
        legend : bool
            Boolean flag for adding a legend

        Returns
        -------
        plt.figure
            Matplotlib figure object
        """
        freqArray = self.freqArray
        fig = (plt.figure(kwargs["fig"].number) if "fig" in kwargs else
               plt.figure(figsize=(20, 2 * self.numChans)))
        plotFonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        color = kwargs["color"] if "color" in kwargs else None
        # suptitle
        st = fig.suptitle(
            "Spectra data from {} to {}".format(self.startTime, self.stopTime),
            fontsize=plotFonts["suptitle"],
        )
        st.set_y(0.98)
        # now plot the data
        dataChans = kwargs["chans"] if "chans" in kwargs else self.chans
        numPlotChans = len(dataChans)
        for idx, chan in enumerate(dataChans):
            ax = plt.subplot(numPlotChans, 1, idx + 1)
            plt.title("Channel {}".format(chan), fontsize=plotFonts["title"])
            # plot the data
            if "label" in kwargs:
                plt.plot(
                    freqArray,
                    np.absolute(self.data[chan]),
                    color=color,
                    label=kwargs["label"],
                )
            else:
                plt.plot(freqArray, np.absolute(self.data[chan]), color=color)
            # add frequency label
            if idx == numPlotChans - 1:
                plt.xlabel("Frequency [Hz]", fontsize=plotFonts["axisLabel"])
            # x axis options
            xlim = kwargs["xlim"] if "xlim" in kwargs else [
                freqArray[0], freqArray[-1]
            ]
            plt.xlim(xlim)
            # y axis options
            if isElectric(chan):
                plt.ylabel("[mV/km]", fontsize=plotFonts["axisLabel"])
            else:
                plt.ylabel("[nT]", fontsize=plotFonts["axisLabel"])
            plt.grid()
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotFonts["axisTicks"])
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            plt.tight_layout(rect=[0, 0.02, 1, 0.96])
            plt.show()

        return fig
예제 #7
0
    def crossplot(self, eFreqI: int, **kwargs) -> Figure:
        """Plots crossplots of statistic components for evaluation frequency index

        Notes
        -----
        By default, the crossplots plotted are
        statistic component 1 vs statistic component 2
        statistic component 3 vs statistic component 4
        etc

        But crossplots can be explicity set by using the crossplots keyword. They should be specified as a list of a list of strings
        e.g.
        crossplots = [[component2, component3], [component1, component4]]

        Parameters
        ----------
        eFreqI : int
            Evaluation frequency index
        maskwindows : List, np.ndarray
            Global windows to exclude              
        crossplots : List[List[str]], optional
            The parameters to crossplot
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        clim : List, optional
            Limits for colourbar axis
        xlim : List, optional
            Limits for the x axis
        ylim : List, optional
            Limits for the y axis
        colortitle : str, optional
            Title for the colourbar
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object            
        """
        # deal with maskwindows, which are global indices
        maskWindows = kwargs["maskwindows"] if "maskwindows" in kwargs else []
        plotIndices = self.getUnmaskedIndices(maskWindows)

        # figure out the crossplots
        if "crossplots" in kwargs:
            crossplots = kwargs["crossplots"]
        else:
            crossplots = list(zip(self.winStats[::2], self.winStats[1::2]))

        # plot parameters
        nrows, ncols = self.getRowsCols(self.maxcols, numStats=len(crossplots))
        eFreq = self.evalFreq[eFreqI]

        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        fig = (plt.figure(kwargs["fig"].number) if "fig" in kwargs else
               plt.figure(figsize=(4 * ncols, 5 * nrows)))
        st = fig.suptitle(
            "{} crossplots for evaluation frequency: {:.3f} Hz".format(
                self.statName, eFreq),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        # now plot the data
        for idx, cplot in enumerate(crossplots):
            ax = plt.subplot(nrows, ncols, idx + 1)
            plt.title("{} vs. {}".format(cplot[0], cplot[1]),
                      fontsize=plotfonts["title"])
            label = kwargs["label"] if "label" in kwargs else eFreq

            # the colourdata
            colourbool, colourdata, cmap = self.calcColourData(
                self.globalIndices, cplot[0], eFreqI, kwargs)

            # get plot data
            plotI1 = self.winStats.index(cplot[0])
            plotData1 = np.squeeze(self.stats[:, eFreqI, plotI1])
            plotI2 = self.winStats.index(cplot[1])
            plotData2 = np.squeeze(self.stats[:, eFreqI, plotI2])
            if plotIndices is not None:
                plotData1 = plotData1[plotIndices]
                plotData2 = plotData2[plotIndices]
                colourdata = colourdata[plotIndices]

            # scatter plot
            scat = plt.scatter(
                plotData1,
                plotData2,
                c=colourdata,
                edgecolors="none",
                marker="o",
                s=12,
                cmap=cmap,
                label=label,
            )
            clim = (kwargs["clim"] if "clim" in kwargs else
                    [colourdata.min(), colourdata.max()])
            scat.set_clim(clim)
            # x axis options
            plt.xlabel("Value {}".format(cplot[0]),
                       fontsize=plotfonts["axisLabel"])
            if "xlim" in kwargs:
                plt.xlim(kwargs["xlim"])
            # y axis options
            plt.ylabel("Value {}".format(cplot[1]),
                       fontsize=plotfonts["axisLabel"])
            if "ylim" in kwargs:
                plt.ylim(kwargs["ylim"])
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            plt.grid(True, ls="--")
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            fig.tight_layout(rect=[0.02, 0.02, 0.85, 0.92])
            cax = fig.add_axes([0.88, 0.10, 0.03, 0.80])
            if not colourbool:
                self.addColourbarDates(scat, cax, "Time", plotfonts)
            else:
                colourtitle = (kwargs["colortitle"]
                               if "colortitle" in kwargs else "Value")
                self.addColourbar(scat, cax, colourtitle, plotfonts)
            plt.show()

        return fig
예제 #8
0
    def histogram(self, eFreqI: int, **kwargs) -> Figure:
        """Plot statistics for evaluation frequency index

        Plots a histogram of each statistic with bins on the xaxis and count on the yaxis. Ideal for exploring the distribution of statistic values over the windows.

        Parameters
        ----------
        eFreqI : int
            Evaluation frequency index
        maskwindows : List, np.ndarray
            Global windows to exclude            
        numbins : int
            The number of bins for the histogram data binning
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object            
        """
        # deal with maskwindows, which are global indices
        maskWindows = kwargs["maskwindows"] if "maskwindows" in kwargs else []
        plotIndices = self.getUnmaskedIndices(maskWindows)
        eFreq = self.evalFreq[eFreqI]

        # plot options
        numbins = kwargs["numbins"] if "numbins" in kwargs else 40
        nrows, ncols = self.getRowsCols(self.maxcols)

        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()
        fig = (plt.figure(kwargs["fig"].number) if "fig" in kwargs else
               plt.figure(figsize=(4 * ncols, 4 * nrows)))
        st = fig.suptitle(
            "{} data for evaluation frequency: {}".format(
                self.statName, eFreq),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        # plot the data
        for idx, val in enumerate(self.winStats):
            ax = plt.subplot(nrows, ncols, idx + 1)
            plt.title("Value {}".format(val), fontsize=plotfonts["title"])
            label = kwargs["label"] if "label" in kwargs else eFreq

            # data
            plotData = np.squeeze(self.stats[:, eFreqI, idx])
            if plotIndices is not None:
                plotData = plotData[plotIndices]
            # remove infinities and nans
            plotData = plotData[np.isfinite(plotData)]

            # x axis options
            xlim = (kwargs["xlim"] if "xlim" in kwargs else
                    [np.min(plotData), np.max(plotData)])
            plt.xlim(xlim)
            plt.xlabel("Value", fontsize=plotfonts["axisLabel"])
            # now plot with xlim in mind
            plt.hist(plotData,
                     numbins,
                     range=xlim,
                     facecolor="red",
                     alpha=0.75)
            # y axis options
            plt.ylabel("Count", fontsize=plotfonts["axisLabel"])
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            plt.grid(True, ls="--")
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
            plt.show()

        return fig
예제 #9
0
    def view(self, eFreqI: int, **kwargs) -> Figure:
        """Plot statistics for evaluation frequency index

        Plots a simple scatter of each statistic with datetime on the xaxis (datetime of the window start dates). Number of subplots is equal to numStaStatPerWindow.

        Parameters
        ----------
        eFreqI : int
            Evaluation frequency index
        maskwindows : List, np.ndarray
            Global windows to exclude
        fig : matplotlib.pyplot.figure, optional
            A figure object
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        clim : List, optional
            Limits for colourbar axis
        xlim : List, optional
            Limits for the x axis
        ylim : List, optional
            Limits for the y axis
        colortitle : str, optional
            Title for the colourbar
        legened : bool
            Boolean flag for adding a legend
        
        Returns
        -------
        plt.figure
            Matplotlib figure object        
        """
        # get windows to plot and global dates
        maskWindows = kwargs["maskwindows"] if "maskwindows" in kwargs else []
        plotIndices = self.getUnmaskedIndices(maskWindows)
        globalDates = self.getGlobalDates()
        eFreq = self.evalFreq[eFreqI]

        # plot params
        nrows, ncols = self.getRowsCols(self.maxcols)
        plotfonts = kwargs[
            "plotfonts"] if "plotfonts" in kwargs else getViewFonts()

        fig: plt.figure = (plt.figure(kwargs["fig"].number) if "fig" in kwargs
                           else plt.figure(figsize=(4 * ncols, 5 * nrows)))
        st = fig.suptitle(
            "{} data for evaluation frequency: {}".format(
                self.statName, eFreq),
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        # plot the data
        for idx, val in enumerate(self.winStats):
            ax = plt.subplot(nrows, ncols, idx + 1)
            plt.title("Value {}".format(val), fontsize=plotfonts["title"])
            label = kwargs["label"] if "label" in kwargs else eFreq

            # limit the data by plotIndices if not False
            plotData = np.squeeze(self.stats[:, eFreqI, idx])
            plotDates = globalDates
            if plotIndices is not None:
                plotData = plotData[plotIndices]
                plotDates = plotDates[plotIndices]

            # the colourdata
            colourbool, colourdata, cmap = self.calcColourData(
                plotData, val, eFreqI, kwargs)
            # scatter plot
            if not colourbool:
                scat = plt.scatter(
                    plotDates,
                    plotData,
                    edgecolors="none",
                    marker="o",
                    s=12,
                    label=label,
                )
            else:
                scat = plt.scatter(
                    plotDates,
                    plotData,
                    c=colourdata,
                    edgecolors="none",
                    marker="o",
                    s=12,
                    cmap=cmap,
                    label=label,
                )
                clim = (kwargs["clim"] if
                        ("clim" in kwargs and len(kwargs["clim"]) > 0) else
                        [colourdata.min(), colourdata.max()])
                scat.set_clim(clim)
            # x axis options
            plt.xlabel("Time", fontsize=plotfonts["axisLabel"])
            xlim = (kwargs["xlim"] if
                    ("xlim" in kwargs and len(kwargs["xlim"]) > 0) else
                    [globalDates[0], globalDates[-1]])
            plt.xlim(xlim)
            ax.format_xdata = DateFormatter("%H-%M-%S")
            fig.autofmt_xdate()
            # y axis options
            if "ylim" in kwargs and len(kwargs["ylim"]) > 0:
                plt.ylim(kwargs["ylim"])
            plt.ylabel("Value {}".format(val), fontsize=plotfonts["axisLabel"])
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            plt.grid(True, ls="--")
            # legend
            if "legend" in kwargs and kwargs["legend"]:
                plt.legend(loc=4)

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            if colourbool:
                fig.tight_layout(rect=[0.02, 0.02, 0.85, 0.92])
                cax = fig.add_axes([0.88, 0.10, 0.03, 0.80])
                colourtitle = (kwargs["colortitle"]
                               if "colortitle" in kwargs else "Value")
                self.addColourbar(scat, cax, colourtitle, plotfonts)
            else:
                fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
            plt.show()

        return fig
예제 #10
0
    def viewTipper(self, **kwargs) -> Figure:
        """Plots tipper data where available

        For length data, both axes are log scale (period and length). For angle data, period is in log scale and phase is linear scale.
        Units, x axis is seconds, length is dimensionless and angle is degrees.

        Parameters
        ----------
        fig : matplotlib.pyplot.figure, optional
            A figure object
        cols : bool, optional
            There are three tipper plots: tipper length, tipper real angle, tipper imaginary angle. These can either be plotted in rows or columns. Set to True to plot in with one row and three columns.
        colours : str, optional
            Colour of plot
        mk : str, optional
            Plot marker type
        ls : str, optional
            Line style  
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        length_ylim : List, optional
            Limits for the length y axis
        angle_ylim : List, optional
            Limits for the angle y axis            
        """
        if "HzHx" not in self.polarisations or "HzHy" not in self.polarisations:
            return False

        # rows or columns
        cols = kwargs["cols"] if "cols" in kwargs else True
        if cols:
            nrows = 1
            ncols = 3
        else:
            nrows = 3
            ncols = 1
        # plot options
        mk = kwargs["mk"] if "mk" in kwargs else "o"
        ls = kwargs["ls"] if "ls" in kwargs else "none"
        plotfonts = kwargs["plotfonts"] if "plotfonts" in kwargs else getViewFonts()

        # limits
        xlim = kwargs["xlim"] if "xlim" in kwargs else [1e-3, 1e4]
        length_ylim = kwargs["length_ylim"] if "length_ylim" in kwargs else [1e-2, 1e3]
        angle_ylim = kwargs["angle_ylim"] if "angle_ylim" in kwargs else [-30, 30]

        fig = (
            plt.figure(kwargs["fig"].number)
            if "fig" in kwargs
            else plt.figure(figsize=(16, 7))
        )
        st = fig.suptitle("Tipper")
        st.set_y(0.98)

        # plot
        tipperLength, tipperAngleRe, tipperAngleIm = self.getTipper()
        # lengthError, angleError = self.getTipperErrors()
        label = kwargs["label"] if "label" in kwargs else "tipper"
        # plot resistivity
        ax1 = plt.subplot(nrows, ncols, 1)
        plt.title("Tipper Length")
        ax1.errorbar(
            self.period,
            tipperLength,
            yerr=tipperLength / 50,
            ls=ls,
            marker=mk,
            markerfacecolor="white",
            markersize=9,
            color="red",
            ecolor="red",
            mew=1.1,
            elinewidth=1.0,
            capsize=4,
            barsabove=False,
            label=label,
        )
        ax1.set_xscale("log")
        ax1.set_yscale("log")
        # axis options
        plt.xlabel("Period [s]", fontsize=plotfonts["axisLabel"])
        plt.ylabel("Length [dimensionless]", fontsize=plotfonts["axisLabel"])
        plt.xlim(xlim)
        plt.ylim(length_ylim)
        # set tick sizes and legend
        for lab in ax1.get_xticklabels() + ax1.get_yticklabels():
            lab.set_fontsize(plotfonts["axisTicks"])
        leg = plt.legend(loc="upper right", fontsize=plotfonts["legend"])
        leg.get_frame().set_linewidth(0.0)
        leg.get_frame().set_facecolor("w")
        plt.grid(True, ls="--")

        # plot real tipper angles
        ax2 = plt.subplot(nrows, ncols, 2)
        plt.title("Tipper Angle Real")
        ax2.errorbar(
            self.period,
            tipperAngleRe,
            yerr=tipperAngleRe / 50,
            ls="none",
            marker=mk,
            markerfacecolor="white",
            markersize=9,
            color="red",
            ecolor="red",
            mew=1.1,
            elinewidth=1.0,
            capsize=4,
            barsabove=False,
            label=label,
        )
        ax2.set_xscale("log")
        # axis options
        plt.xlabel("Period [s]", fontsize=plotfonts["axisLabel"])
        plt.ylabel("Angle [degrees]", fontsize=plotfonts["axisLabel"])
        plt.xlim(xlim)
        plt.ylim(angle_ylim)
        # set tick sizes
        for lab in ax2.get_xticklabels() + ax2.get_yticklabels():
            lab.set_fontsize(plotfonts["axisTicks"])
        leg = plt.legend(loc="upper right", fontsize=plotfonts["legend"])
        leg.get_frame().set_linewidth(0.0)
        leg.get_frame().set_facecolor("w")
        plt.grid(True, ls="--")

        # plot imaginary tipper angles
        ax3 = plt.subplot(nrows, ncols, 3)
        plt.title("Tipper Angle Imaginary")
        ax3.errorbar(
            self.period,
            tipperAngleIm,
            yerr=tipperAngleIm / 50,
            ls="none",
            marker=mk,
            markerfacecolor="white",
            markersize=9,
            color="red",
            ecolor="red",
            mew=1.1,
            elinewidth=1.0,
            capsize=4,
            barsabove=False,
            label=label,
        )
        ax3.set_xscale("log")
        # axis options
        plt.xlabel("Period [s]", fontsize=plotfonts["axisLabel"])
        plt.ylabel("Angle [degrees]", fontsize=plotfonts["axisLabel"])
        plt.xlim(xlim)
        plt.ylim(angle_ylim)
        # set tick sizes
        for lab in ax3.get_xticklabels() + ax3.get_yticklabels():
            lab.set_fontsize(plotfonts["axisTicks"])
        leg = plt.legend(loc="upper right", fontsize=plotfonts["legend"])
        leg.get_frame().set_linewidth(0.0)
        leg.get_frame().set_facecolor("w")
        plt.grid(True, ls="--")

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            # layout options
            plt.tight_layout()
            fig.subplots_adjust(top=0.90)
            plt.show()

        return fig
예제 #11
0
    def viewImpedance(self, **kwargs) -> Figure:
        """Plots the transfer function data

        For resistivity data, both axes are log scale (period and resistivity). For phase data, period is in log scale and phase is linear scale.
        Units, x axis is seconds, resistivity is Ohm m and phase is degrees.

        Parameters
        ----------
        polarisations : List[str], optional
            Polarisations to plot
        fig : matplotlib.pyplot.figure, optional
            A figure object
        oneplot : bool, optional   
            Boolean flag for plotting all polarisations on one plot rather than separate plots               
        colours : Dict[str, str], optional
            Colours dictionary for plotting impedance components 
        mk : str, optional
            Plot marker type
        ls : str, optional
            Line style  
        plotfonts : Dict, optional
            A dictionary of plot fonts
        label : str, optional
            Label for the plots
        xlim : List, optional
            Limits for the x axis
        res_ylim : List, optional
            Limits for the resistivity y axis
        phase_ylim : List, optional
            Limits for the phase y axis 

        Returns
        -------
        plt.figure
            Matplotlib figure object            
        """
        polarisations = (
            kwargs["polarisations"] if "polarisations" in kwargs else self.polarisations
        )

        # limits
        xlim = kwargs["xlim"] if "xlim" in kwargs else [1e-3, 1e4]
        res_ylim = kwargs["res_ylim"] if "res_ylim" in kwargs else [1e-2, 1e3]
        phase_ylim = kwargs["phase_ylim"] if "phase_ylim" in kwargs else [-30, 120]

        # markers
        colours = (
            kwargs["colours"] if "colours" in kwargs else transferFunctionColours()
        )
        mk = kwargs["mk"] if "mk" in kwargs else "o"
        ls = kwargs["ls"] if "ls" in kwargs else "none"
        plotfonts = kwargs["plotfonts"] if "plotfonts" in kwargs else getViewFonts()

        # calculate number of rows and columns
        oneplot = False
        if "oneplot" in kwargs and kwargs["oneplot"]:
            oneplot = True
        nrows = 2
        ncols = 1 if oneplot else len(polarisations)
        # a multiplier to make sure all the components end up on the right plot
        plotNumMult = 0 if ncols > 1 else 1

        # plot
        if "fig" in kwargs:
            fig = plt.figure(kwargs["fig"].number)
        else:
            figsize = getTransferFunctionFigSize(oneplot, len(polarisations))
            fig = plt.figure(figsize=figsize)

        st = fig.suptitle(
            "Impedance tensor apparent resistivity and phase",
            fontsize=plotfonts["suptitle"],
        )
        st.set_y(0.98)

        for idx, pol in enumerate(polarisations):
            res, phase = self.getResAndPhase(pol)
            resError, phaseError = self.getResAndPhaseErrors(pol)
            label = kwargs["label"] + " - {}".format(pol) if "label" in kwargs else pol
            # plot resistivity
            ax1 = plt.subplot(nrows, ncols, idx + 1 - plotNumMult * idx)
            # the title
            if not oneplot:
                plt.title("Polarisation {}".format(pol), fontsize=plotfonts["title"])
            else:
                plt.title(
                    "Polarisations {}".format(listToString(polarisations)),
                    fontsize=plotfonts["title"],
                )
            # plot the data
            ax1.errorbar(
                self.period,
                res,
                yerr=resError,
                ls=ls,
                marker=mk,
                markersize=7,
                markerfacecolor="white",
                markeredgecolor=colours[pol],
                mew=1.1,
                color=colours[pol],
                ecolor=colours[pol],
                elinewidth=1.0,
                capsize=4,
                barsabove=False,
                label=label,
            )
            ax1.set_xscale("log")
            ax1.set_yscale("log")
            ax1.set_aspect("equal", adjustable="box")
            # axis options
            plt.ylabel("Apparent Res. [Ohm m]", fontsize=plotfonts["axisLabel"])
            plt.xlim(xlim)
            plt.ylim(res_ylim)
            # set tick sizes
            for lab in ax1.get_xticklabels() + ax1.get_yticklabels():
                lab.set_fontsize(plotfonts["axisTicks"])

            # plot phase
            ax2 = plt.subplot(nrows, ncols, ncols + idx + 1 - plotNumMult * idx)
            # plot the data
            ax2.errorbar(
                self.period,
                phase,
                yerr=phaseError,
                ls="none",
                marker=mk,
                markersize=7,
                markerfacecolor="white",
                markeredgecolor=colours[pol],
                mew=1.1,
                color=colours[pol],
                ecolor=colours[pol],
                elinewidth=1.0,
                capsize=4,
                barsabove=False,
                label=label,
            )
            ax2.set_xscale("log")
            # axis options
            plt.xlabel("Period [s]", fontsize=plotfonts["axisLabel"])
            plt.ylabel("Phase [degrees]", fontsize=plotfonts["axisLabel"])
            plt.xlim(xlim)
            plt.ylim(phase_ylim)
            # set tick sizes
            for lab in ax2.get_xticklabels() + ax2.get_yticklabels():
                lab.set_fontsize(plotfonts["axisTicks"])

        # add the legend
        for idx, pol in enumerate(polarisations):
            ax1 = plt.subplot(nrows, ncols, idx + 1 - plotNumMult * idx)
            leg = plt.legend(loc="lower left", fontsize=plotfonts["legend"])
            leg.get_frame().set_linewidth(0.0)
            leg.get_frame().set_facecolor("w")
            plt.grid(True, ls="--")
            ax2 = plt.subplot(nrows, ncols, ncols + idx + 1 - plotNumMult * idx)
            leg = plt.legend(loc="lower left", fontsize=plotfonts["legend"])
            leg.get_frame().set_linewidth(0.0)
            leg.get_frame().set_facecolor("w")
            plt.grid(True, ls="--")

        # show if the figure is not in keywords
        if "fig" not in kwargs:
            # layout options
            plt.tight_layout()
            fig.subplots_adjust(top=0.92)
            plt.show()

        return fig