Example #1
0
"powerSpectralDensity",
"polarisationDirection",
"partialCoherence",
"transferFunction",
"resPhase",
"""


# need the project path for loading
projectPath = os.path.join("exampleProject")
projData = loadProject(projectPath, configFile="ex1_04_config.ini")
projData.printInfo()
stats, remotestats = getStatNames()

# plot the examples we need
options = plotOptionsSpec()
options["figsize"] = (20, 7)
options["plotfonts"]["suptitle"] = 18
options["plotfonts"]["title"] = 16

# coherence
viewStatistic(
    projData, "site1", 128, "coherence", save=True, show=False, plotoptions=options
)
viewStatisticHistogram(
    projData, "site1", 128, "coherence", save=True, show=False, plotoptions=options
)

# polarisation directions
options["figsize"] = (17, 12)
viewStatistic(
Example #2
0
def viewStatisticCrossplot(projData: ProjectData, site: str,
                           sampleFreq: Union[int, float], stat: str,
                           crossplots: List[List[str]],
                           **kwargs) -> Union[plt.figure, None]:
    """View statistic data for a single sampling frequency of a site
    
    Parameters
    ----------
    projData : ProjectData
        A project instance
    site : str
        The site for which to plot statistics
    stat : str
        The statistic to plot
    sampleFreq : float
        The sampling frequency for which to plot statistics
    crossplots : List[List[str]]
        The statistic element pairs to crossplot
    declevel : int
        The decimation level to plot
    eFreqI : int
        The evaluation frequency index
    specdir : str
        The spectra directory
    maskname : str
        Mask name         
    xlim : List, optional
        Limits for the x axis
    ylim : List, optional
        Limits for the y axis
    maxcols : int
        The maximum number of columns in the plots        
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options    

    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None and the figure is closed.
    """

    options = {}
    options["declevel"] = 0
    options["eFreqI"] = 0
    options["specdir"] = projData.config.configParams["Spectra"]["specdir"]
    options["maskname"] = ""
    options["xlim"] = []
    options["ylim"] = []
    options["maxcols"] = 2
    options["show"] = True
    options["save"] = False
    options["plotoptions"] = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText(
        "Plotting crossplot for statistic {}, site {} and sampling frequency {}"
        .format(stat, site, sampleFreq))

    statData = getStatisticDataForSampleFreq(
        projData,
        site,
        sampleFreq,
        stat,
        declevel=options["declevel"],
        specdir=options["specdir"],
    )
    statMeas = list(statData.keys())
    # get the evaluation frequency
    eFreq = statData[statMeas[0]].evalFreq[options["eFreqI"]]

    # get the mask data
    maskWindows = []
    if options["maskname"] != "":
        maskData = getMaskData(projData, site, options["maskname"], sampleFreq)
        maskWindows = maskData.getMaskWindowsFreq(options["declevel"],
                                                  options["eFreqI"])

    # plot information
    nrows, ncols = getPlotRowsAndCols(options["maxcols"], len(crossplots))

    plotfonts = options["plotoptions"]["plotfonts"]
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])
    # suptitle
    st = fig.suptitle(
        "{} crossplots for {}, sampling frequency {} Hz, decimation level {} and evaluation frequency {} Hz"
        .format(stat, site, sampleFreq, options["declevel"], 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("Crossplot {}".format(cplot), fontsize=plotfonts["title"])

        for meas in statMeas:
            stats = statData[meas].getStats(maskwindows=maskWindows)
            plotI1 = statData[meas].winStats.index(cplot[0])
            plotData1 = np.squeeze(stats[:, options["eFreqI"], plotI1])
            plotI2 = statData[meas].winStats.index(cplot[1])
            plotData2 = np.squeeze(stats[:, options["eFreqI"], plotI2])
            scat = plt.scatter(plotData1,
                               plotData2,
                               edgecolors="none",
                               marker="o",
                               s=12,
                               label=meas)

        # x axis options
        if len(options["xlim"]) > 0:
            plt.xlim(options["xlim"])
        if len(options["ylim"]) > 0:
            plt.ylim(options["ylim"])
        plt.xlabel(cplot[0], fontsize=plotfonts["axisLabel"])
        plt.ylabel(cplot[1], fontsize=plotfonts["axisLabel"])
        plt.grid(True)
        # set tick sizes
        for label in ax.get_xticklabels() + ax.get_yticklabels():
            label.set_fontsize(plotfonts["axisTicks"])
        plt.legend(loc=2, markerscale=4, fontsize=plotfonts["legend"])

    # plot format, show and save
    fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
    if options["save"]:
        impath = projData.imagePath
        sampleFreqStr = fileFormatSampleFreq(sampleFreq)
        filename = "statCrossplot_{:s}_{:s}_{:s}_dec{:d}_efreq{:d}_{:s}".format(
            stat,
            site,
            sampleFreqStr,
            options["declevel"],
            options["eFreqI"],
            options["specdir"],
        )
        if options["maskname"] != "":
            filename = "{}_{}".format(filename, options["maskname"])
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig
Example #3
0
from resistics.project.projectIO import loadProject

projectPath = os.path.join("tutorialProject")
projData = loadProject(projectPath)

# calculate another set of spectra for the 128 Hz data with notching at 50Hz and 16.667Hz
from resistics.project.projectSpectra import calculateSpectra

calculateSpectra(projData, sampleFreqs=[128], notch=[50], specdir="notch")
projData.refresh()

# view the spectra
from resistics.utilities.utilsPlotter import plotOptionsSpec, getPaperFonts
from resistics.project.projectSpectra import viewSpectra, viewSpectraSection

plotOptions = plotOptionsSpec(plotfonts=getPaperFonts())
viewSpectra(
    projData,
    "site1",
    "meas_2012-02-10_11-30-00",
    specdir="notch",
    plotoptions=plotOptions,
    show=True,
    save=True,
)

viewSpectraSection(
    projData,
    "site1",
    "meas_2012-02-10_11-30-00",
    specdir="notch",
Example #4
0
def viewStatisticHistogram(projData: ProjectData, site: str, sampleFreq: float,
                           stat: str, **kwargs) -> Union[plt.figure, None]:
    """View statistic histograms for a single sampling frequency of a site
    
    Parameters
    ----------
    projData : ProjectData
        A project instance
    site : str
        The site for which to plot statistics
    stat : str
        The statistic to plot
    sampleFreq : float
        The sampling frequency for which to plot statistics
    declevel : int
        The decimation level to plot
    eFreqI : int
        The evaluation frequency index       
    specdir : str
        The spectra directory        
    maskname : str
        Mask name 
    numbins : int
        The number of bins for the histogram data binning
    xlim : List, optional
        Limits for the x axis
    maxcols : int
        The maximum number of columns in the plots
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options    

    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None.
    """

    options = {}
    options["declevel"] = 0
    options["eFreqI"] = 0
    options["specdir"] = projData.config.configParams["Spectra"]["specdir"]
    options["maskname"] = ""
    options["numbins"] = 40
    options["xlim"] = []
    options["maxcols"] = 4
    options["show"] = True
    options["save"] = False
    options["plotoptions"] = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText(
        "Plotting histogram for statistic {}, site {} and sampling frequency {}"
        .format(stat, site, sampleFreq))

    statData = getStatisticDataForSampleFreq(
        projData,
        site,
        sampleFreq,
        stat,
        declevel=options["declevel"],
        specdir=options["specdir"],
    )
    statMeas = list(statData.keys())
    # get the statistic components
    statComponents = statData[statMeas[0]].winStats
    # get the evaluation frequency
    eFreq = statData[statMeas[0]].evalFreq[options["eFreqI"]]

    # get the mask data
    maskWindows = []
    if options["maskname"] != "":
        maskData = getMaskData(projData, site, options["maskname"], sampleFreq)
        maskWindows = maskData.getMaskWindowsFreq(options["declevel"],
                                                  options["eFreqI"])

    # plot information
    nrows, ncols = getPlotRowsAndCols(options["maxcols"], len(statComponents))
    numbins = options["numbins"]

    plotfonts = options["plotoptions"]["plotfonts"]
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])
    # suptitle
    st = fig.suptitle(
        "{} histogram for {}, sampling frequency {} Hz, decimation level {} and evaluation frequency {} Hz"
        .format(stat, site, sampleFreq, options["declevel"], eFreq),
        fontsize=plotfonts["suptitle"],
    )
    st.set_y(0.98)

    # now plot the data
    for idx, val in enumerate(statComponents):
        ax = plt.subplot(nrows, ncols, idx + 1)
        plt.title("Histogram {}".format(val), fontsize=plotfonts["title"])

        plotData = np.empty(shape=(0))
        for meas in statMeas:
            stats = statData[meas].getStats(maskwindows=maskWindows)
            plotData = np.concatenate(
                (plotData, np.squeeze(stats[:, options["eFreqI"], idx])))
        # remove infinities and nans
        plotData = plotData[np.isfinite(plotData)]

        # x axis options
        xlim = (options["xlim"] if len(options["xlim"]) > 0 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)
        plt.grid()
        # 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"])

    # plot format, show and save
    fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
    if options["save"]:
        impath = projData.imagePath
        sampleFreqStr = fileFormatSampleFreq(sampleFreq)
        filename = "statHist_{:s}_{:s}_{:s}_dec{:d}_efreq{:d}_{:s}".format(
            stat,
            site,
            sampleFreqStr,
            options["declevel"],
            options["eFreqI"],
            options["specdir"],
        )
        if options["maskname"] != "":
            filename = "{}_{}".format(filename, options["maskname"])
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig
Example #5
0
def viewStatistic(projData: ProjectData, site: str, sampleFreq: Union[int,
                                                                      float],
                  stat: str, **kwargs) -> Union[plt.figure, None]:
    """View statistic data for a single sampling frequency of a site
    
    Parameters
    ----------
    projData : ProjectData
        A project instance
    site : str
        The site for which to plot statistics
    stat : str
        The statistic to plot
    sampleFreq : float
        The sampling frequency for which to plot statistics
    declevel : int
        The decimation level to plot
    eFreqI : int
        The evaluation frequency index
    specdir : str
        The spectra directory
    maskname : str
        Mask name         
    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
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options    

    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None and the figure is closed.
    """

    options = {}
    options["declevel"] = 0
    options["eFreqI"] = 0
    options["specdir"] = projData.config.configParams["Spectra"]["specdir"]
    options["maskname"] = ""
    options["clim"] = []
    options["xlim"] = []
    options["ylim"] = []
    options["colortitle"] = ""
    options["show"] = True
    options["save"] = False
    options["plotoptions"] = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText(
        "Plotting statistic {} for site {} and sampling frequency {}".format(
            stat, site, sampleFreq))
    statData = getStatisticDataForSampleFreq(
        projData,
        site,
        sampleFreq,
        stat,
        declevel=options["declevel"],
        specdir=options["specdir"],
    )
    # get the statistics
    statMeas = list(statData.keys())
    # get the evaluation frequency
    eFreq = statData[statMeas[0]].evalFreq[options["eFreqI"]]

    # get the mask data
    maskWindows = []
    if options["maskname"] != "":
        maskData = getMaskData(projData, site, options["maskname"], sampleFreq)
        maskWindows = maskData.getMaskWindowsFreq(options["declevel"],
                                                  options["eFreqI"])

    # setup the figure
    plotfonts = options["plotoptions"]["plotfonts"]
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])

    # get the date limits
    siteData = projData.getSiteData(site)
    if len(options["xlim"]) == 0:
        start = siteData.getMeasurementStart(statMeas[0])
        end = siteData.getMeasurementEnd(statMeas[0])
        for meas in statMeas:
            start = min(start, siteData.getMeasurementStart(meas))
            end = max(end, siteData.getMeasurementEnd(meas))
        options["xlim"] = [start, end]

    # do the plots
    for meas in statMeas:
        statData[meas].view(
            options["eFreqI"],
            fig=fig,
            xlim=options["xlim"],
            ylim=options["ylim"],
            clim=options["clim"],
            label=meas,
            plotfonts=options["plotoptions"]["plotfonts"],
            maskwindows=maskWindows,
        )
    # add a legened
    plt.legend(markerscale=4, fontsize=plotfonts["legend"])

    # do the title after all the plots
    st = fig.suptitle(
        "{} values for {}, sampling frequency = {:.2f} Hz, decimation level = {} and evaluation frequency {} Hz"
        .format(stat, site, sampleFreq, options["declevel"], eFreq),
        fontsize=plotfonts["suptitle"],
    )

    # plot format, show and save
    fig.tight_layout(rect=[0.02, 0.02, 0.98, 0.92])
    if options["save"]:
        impath = projData.imagePath
        sampleFreqStr = fileFormatSampleFreq(sampleFreq)
        filename = "stat_{:s}_{:s}_{:s}_dec{:d}_efreq{:d}_{:s}".format(
            stat,
            site,
            sampleFreqStr,
            options["declevel"],
            options["eFreqI"],
            options["specdir"],
        )
        if options["maskname"] != "":
            filename = "{}_{}".format(filename, options["maskname"])
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig
Example #6
0
def viewSpectraStack(
    projData: ProjectData, site: str, meas: str, **kwargs
) -> Union[plt.figure, None]:
    """View spectra stacks for a measurement

    Parameters
    ----------
    projData : projecData
        The project data
    site : str
        The site to view
    meas: str
        The measurement of the site to view
    chans : List[str], optional
        Channels to plot
    declevel : int, optional
        Decimation level to plot
    numstacks : int, optional
        The number of windows to stack
    coherences : List[List[str]], optional
        A list of coherences to add, specified as [["Ex", "Hy"], ["Ey", "Hx"]] 
    specdir : str, optional
        String that specifies spectra directory for the measurement
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options
    
    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None and the figure is closed.
    """

    options = {}
    options["chans"] = []
    options["declevel"] = 0
    options["numstacks"] = 10
    options["coherences"] = []
    options["specdir"] = projData.config.configParams["Spectra"]["specdir"]
    options["show"] = True
    options["save"] = False
    options["plotoptions"] = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText(
        "Plotting spectra stack for measurement {} and site {}".format(meas, site)
    )
    specReader = getSpecReader(projData, site, meas, **options)

    # channels
    dataChans = specReader.getChannels()
    if len(options["chans"]) > 0:
        dataChans = options["chans"]
    numChans = len(dataChans)

    # get windows
    numWindows = specReader.getNumWindows()
    sampleFreqDec = specReader.getSampleFreq()
    f = specReader.getFrequencyArray()

    # calculate num of windows to stack in each set
    stackSize = int(np.floor(1.0 * numWindows / options["numstacks"]))

    # calculate number of rows - in case interested in coherences too
    nrows = (
        2
        if len(options["coherences"]) == 0
        else 2 + np.ceil(1.0 * len(options["coherences"]) / numChans)
    )

    # setup the figure
    plotfonts = options["plotoptions"]["plotfonts"]
    cmap = colorbarMultiline()
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])
    st = fig.suptitle(
        "Spectra stack, fs = {:.6f} [Hz], decimation level = {:2d}, windows in each set = {:d}".format(
            sampleFreqDec, options["declevel"], stackSize
        ),
        fontsize=plotfonts["suptitle"],
    )
    st.set_y(0.98)

    # do the stacking
    for iP in range(0, options["numstacks"]):
        stackStart = iP * stackSize
        stackStop = min(stackStart + stackSize, numWindows)
        color = cmap(iP/options["numstacks"])
        # dictionaries to hold data for this section
        stackedData = {}
        ampData = {}
        phaseData = {}
        powerData = {}

        # assign initial zeros
        for c in dataChans:
            stackedData[c] = np.zeros(shape=(specReader.getDataSize()), dtype="complex")
            ampData[c] = np.zeros(shape=(specReader.getDataSize()), dtype="complex")
            phaseData[c] = np.zeros(shape=(specReader.getDataSize()), dtype="complex")
            for c2 in dataChans:
                powerData[c + c2] = np.zeros(
                    shape=(specReader.getDataSize()), dtype="complex"
                )

        # now stack the data and create nice plots
        for iW in range(stackStart, stackStop):
            winData = specReader.readBinaryWindowLocal(iW)
            for c in dataChans:
                stackedData[c] += winData.data[c]
                ampData[c] += np.absolute(winData.data[c])
                phaseData[c] += np.angle(winData.data[c]) * (180.0 / np.pi)
                # get coherency data
                for c2 in dataChans:
                    powerData[c + c2] += winData.data[c] * np.conjugate(
                        winData.data[c2]
                    )
            if iW == stackStart:
                startTime = winData.startTime
            if iW == stackStop - 1:
                stopTime = winData.stopTime

        # scale powers and stacks
        ampLim = options["plotoptions"]["amplim"]
        for idx, c in enumerate(dataChans):
            stackedData[c] = stackedData[c] / (stackStop - stackStart)
            ampData[c] = ampData[c] / (stackStop - stackStart)
            phaseData[c] = phaseData[c] / (stackStop - stackStart)
            for c2 in dataChans:
                # normalisation
                powerData[c + c2] = 2 * powerData[c + c2] / (stackStop - stackStart)
                # normalisation
                powerData[c + c2][[0, -1]] = powerData[c + c2][[0, -1]] / 2

            # plot
            ax1 = plt.subplot(nrows, numChans, idx + 1)
            plt.title("Amplitude {}".format(c), fontsize=plotfonts["title"])
            h = ax1.semilogy(
                f,
                ampData[c],
                color=color,
                label="{} to {}".format(
                    startTime.strftime("%m-%d %H:%M:%S"),
                    stopTime.strftime("%m-%d %H:%M:%S"),
                ),
            )
            if len(ampLim) > 2:
                ax1.set_ylim(ampLim)
            else:
                ax1.set_ylim(0.01, 1000)
            ax1.set_xlim(0, sampleFreqDec / 2.0)
            if isMagnetic(c):
                ax1.set_ylabel("Amplitude [nT]", fontsize=plotfonts["axisLabel"])
            else:
                ax1.set_ylabel("Amplitude [mV/km]", fontsize=plotfonts["axisLabel"])
            ax1.set_xlabel("Frequency [Hz]", fontsize=plotfonts["axisLabel"])
            plt.grid(True)

            # set tick sizes
            for label in ax1.get_xticklabels() + ax1.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])
            # plot phase
            ax2 = plt.subplot(nrows, numChans, numChans + idx + 1)
            plt.title("Phase {}".format(c), fontsize=plotfonts["title"])
            ax2.plot(
                f,
                phaseData[c],
                color=color,                
                label="{} to {}".format(
                    startTime.strftime("%m-%d %H:%M:%S"),
                    stopTime.strftime("%m-%d %H:%M:%S"),
                ),
            )
            ax2.set_ylim(-180, 180)
            ax2.set_xlim(0, sampleFreqDec / 2.0)
            ax2.set_ylabel("Phase [degrees]", fontsize=plotfonts["axisLabel"])
            ax2.set_xlabel("Frequency [Hz]", fontsize=plotfonts["axisLabel"])
            plt.grid(True)
            # set tick sizes
            for label in ax2.get_xticklabels() + ax2.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])

        # plot coherences
        for idx, coh in enumerate(options["coherences"]):
            c = coh[0]
            c2 = coh[1]
            cohNom = np.power(np.absolute(powerData[c + c2]), 2)
            cohDenom = powerData[c + c] * powerData[c2 + c2]
            coherence = cohNom / cohDenom
            ax = plt.subplot(nrows, numChans, 2 * numChans + idx + 1)
            plt.title("Coherence {} - {}".format(c, c2), fontsize=plotfonts["title"])
            ax.plot(
                f,
                coherence,
                color=color,
                label="{} to {}".format(
                    startTime.strftime("%m-%d %H:%M:%S"),
                    stopTime.strftime("%m-%d %H:%M:%S"),
                ),
            )
            ax.set_ylim(0, 1.1)
            ax.set_xlim(0, sampleFreqDec / 2)
            ax.set_ylabel("Coherence", fontsize=plotfonts["axisLabel"])
            ax.set_xlabel("Frequency [Hz]", fontsize=plotfonts["axisLabel"])
            plt.grid(True)
            # set tick sizes
            for label in ax.get_xticklabels() + ax.get_yticklabels():
                label.set_fontsize(plotfonts["axisTicks"])

    # fig legend and layout
    ax = plt.gca()
    h, l = ax.get_legend_handles_labels()
    fig.tight_layout(rect=[0.01, 0.01, 0.98, 0.81])
    # legend
    legax = plt.axes(position=[0.01, 0.82, 0.98, 0.12], in_layout=False)
    plt.tick_params(left=False, labelleft=False, bottom=False, labelbottom="False")
    plt.box(False)
    legax.legend(h, l, ncol=4, loc="upper center", fontsize=plotfonts["legend"])

    # plot show and save
    if options["save"]:
        impath = projData.imagePath
        filename = "spectraStack_{}_{}_dec{}_{}".format(
            site, meas, options["declevel"], options["specdir"]
        )
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig
Example #7
0
def viewSpectraSection(
    projData: ProjectData, site: str, meas: str, **kwargs
) -> Union[plt.figure, None]:
    """View spectra section for a measurement

    Parameters
    ----------
    projData : projecData
        The project data
    site : str
        The site to view
    meas: str
        The measurement of the site to view    
    chans : List[str], optional
        Channels to plot
    declevel : int, optional
        Decimation level to plot
    specdir : str, optional
        String that specifies spectra directory for the measurement
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options
    
    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None and the figure is closed.
    """

    options = {}
    options["chans"] = []
    options["declevel"] = 0
    options["specdir"] = projData.config.configParams["Spectra"]["specdir"]
    options["show"] = True
    options["save"] = False
    options["plotoptions"] = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText(
        "Plotting spectra section for measurement {} and site {}".format(meas, site)
    )
    specReader = getSpecReader(projData, site, meas, **options)

    # channels
    dataChans = specReader.getChannels()
    if len(options["chans"]) > 0:
        dataChans = options["chans"]

    # get windows
    numWindows = specReader.getNumWindows()
    sampleFreqDec = specReader.getSampleFreq()

    # freq array
    f = specReader.getFrequencyArray()

    # now if plotting a section, ignore plotwindow for now
    if numWindows > 250:
        windows = list(np.linspace(0, numWindows, 250, endpoint=False, dtype=np.int32))
    else:
        windows = np.arange(0, 250)

    # create figure
    plotfonts = options["plotoptions"]["plotfonts"]
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])
    st = fig.suptitle(
        "Spectra section, site = {}, meas = {}, fs = {:.2f} [Hz], decimation level = {:2d}, windows = {:d}, {} to {}".format(
            site,
            meas,
            sampleFreqDec,
            options["declevel"],
            len(windows),
            windows[0],
            windows[-1],
        ),
        fontsize=plotfonts["suptitle"],
    )
    st.set_y(0.98)

    # collect the data
    specData = np.empty(
        shape=(len(windows), len(dataChans), specReader.getDataSize()), dtype="complex"
    )
    dates = []
    for idx, iW in enumerate(windows):
        winData = specReader.readBinaryWindowLocal(iW)
        for cIdx, chan in enumerate(dataChans):
            specData[idx, cIdx, :] = winData.data[chan]
        dates.append(winData.startTime)

    ampLim = options["plotoptions"]["amplim"]
    for idx, chan in enumerate(dataChans):
        ax = plt.subplot(1, len(dataChans), idx + 1)
        plotData = np.transpose(np.absolute(np.squeeze(specData[:, idx, :])))
        if len(ampLim) == 2:
            plt.pcolor(
                dates,
                f,
                plotData,
                norm=LogNorm(vmin=ampLim[0], vmax=ampLim[1]),
                cmap=colorbar2dSpectra(),
            )
        else:
            plt.pcolor(
                dates,
                f,
                plotData,
                norm=LogNorm(vmin=plotData.min(), vmax=plotData.max()),
                cmap=colorbar2dSpectra(),
            )
        cb = plt.colorbar()
        cb.ax.tick_params(labelsize=plotfonts["axisTicks"])
        # set axis limits
        ax.set_ylim(0, specReader.getSampleFreq() / 2.0)
        ax.set_xlim([dates[0], dates[-1]])
        if isMagnetic(chan):
            plt.title("Amplitude {} [nT]".format(chan), fontsize=plotfonts["title"])
        else:
            plt.title("Amplitude {} [mV/km]".format(chan), fontsize=plotfonts["title"])
        ax.set_ylabel("Frequency [Hz]", fontsize=plotfonts["axisLabel"])
        ax.set_xlabel("Time", fontsize=plotfonts["axisLabel"])
        # set tick sizes
        for label in ax.get_xticklabels() + ax.get_yticklabels():
            label.set_fontsize(plotfonts["axisTicks"])
        plt.grid(True)

    # plot format
    fig.autofmt_xdate(rotation=90, ha="center")
    fig.tight_layout(rect=[0.02, 0.02, 0.96, 0.92])

    # plot show and save
    if options["save"]:
        impath = projData.imagePath
        filename = "spectraSection_{}_{}_dec{}_{}".format(
            site, meas, options["declevel"], options["specdir"]
        )
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig
Example #8
0
def viewSpectra(
    projData: ProjectData, site: str, meas: str, **kwargs
) -> Union[plt.figure, None]:
    """View spectra for a measurement

    Parameters
    ----------
    projData : projecData
        The project data
    site : str
        The site to view
    meas: str
        The measurement of the site to view    
    chans : List[str], optional
        Channels to plot
    declevel : int, optional
        Decimation level to plot
    plotwindow : int, str, Dict, optional
        Windows to plot (local). If int, the window with local index plotwindow will be plotted. If string and "all", all the windows will be plotted if there are less than 20 windows, otherwise 20 windows throughout the whole spectra dataset will be plotted. If a dictionary, needs to have start and stop to define a range.
    specdir : str, optional
        String that specifies spectra directory for the measurement
    show : bool, optional
        Show the spectra plot
    save : bool, optional
        Save the plot to the images directory
    plotoptions : Dict, optional
        Dictionary of plot options
    
    Returns
    -------
    matplotlib.pyplot.figure or None
        A matplotlib figure unless the plot is not shown and is saved, in which case None and the figure is closed.
    """

    options = {}
    options["chans"]: List[str] = []
    options["declevel"]: int = 0
    options["plotwindow"]: Union[int, Dict, str] = [0]
    options["specdir"]: str = projData.config.configParams["Spectra"]["specdir"]
    options["show"]: bool = True
    options["save"]: bool = False
    options["plotoptions"]: Dict = plotOptionsSpec()
    options = parseKeywords(options, kwargs)

    projectText("Plotting spectra for measurement {} and site {}".format(meas, site))
    specReader = getSpecReader(projData, site, meas, **options)

    # channels
    dataChans = specReader.getChannels()
    if len(options["chans"]) > 0:
        dataChans = options["chans"]
    numChans = len(dataChans)

    # get windows
    numWindows = specReader.getNumWindows()
    sampleFreqDec = specReader.getSampleFreq()

    # get the window data
    windows = options["plotwindow"]
    if isinstance(windows, str) and windows == "all":
        if numWindows > 20:
            windows = list(
                np.linspace(0, numWindows, 20, endpoint=False, dtype=np.int32)
            )
        else:
            windows = list(np.arange(0, numWindows))
    elif isinstance(windows, int):
        windows = [windows]  # if an integer, make it into a list
    elif isinstance(windows, dict):
        windows = list(np.arange(windows["start"], windows["stop"] + 1))

    # create a figure
    plotfonts = options["plotoptions"]["plotfonts"]
    cmap = colorbarMultiline()
    fig = plt.figure(figsize=options["plotoptions"]["figsize"])
    for iW in windows:
        if iW >= numWindows:
            break
        color = cmap(iW/numWindows)
        winData = specReader.readBinaryWindowLocal(iW)
        winData.view(
            fig=fig,
            chans=dataChans,
            label="{} to {}".format(
                winData.startTime.strftime("%m-%d %H:%M:%S"),
                winData.stopTime.strftime("%m-%d %H:%M:%S"),
            ),
            plotfonts=plotfonts,
            color=color,
        )

    st = fig.suptitle(
        "Spectra plot, site = {}, meas = {}, fs = {:.2f} [Hz], decimation level = {:2d}".format(
            site, meas, sampleFreqDec, options["declevel"]
        ),
        fontsize=plotfonts["suptitle"],
    )
    st.set_y(0.98)

    # put on axis labels etc
    for idx, chan in enumerate(dataChans):
        ax = plt.subplot(numChans, 1, idx + 1)
        plt.title("Amplitude {}".format(chan), fontsize=plotfonts["title"])
        if len(options["plotoptions"]["amplim"]) == 2:
            ax.set_ylim(options["plotoptions"]["amplim"])
        ax.set_xlim(0, specReader.getSampleFreq() / 2.0)
        plt.grid(True)

    # fig legend and formatting
    ax = plt.gca()
    h, l = ax.get_legend_handles_labels()
    fig.tight_layout(rect=[0.02, 0.02, 0.77, 0.92])
    # legend axis
    legax = plt.axes(position=[0.77, 0.02, 0.23, 0.88], in_layout=False)
    plt.tick_params(left=False, labelleft=False, bottom=False, labelbottom="False")
    plt.box(False)
    legax.legend(h, l, loc="upper left", fontsize=plotfonts["legend"])

    # plot show and save
    if options["save"]:
        impath = projData.imagePath
        filename = "spectraData_{}_{}_dec{}_{}".format(
            site, meas, options["declevel"], options["specdir"]
        )
        savename = savePlot(impath, filename, fig)
        projectText("Image saved to file {}".format(savename))
    if options["show"]:
        plt.show(block=options["plotoptions"]["block"])
    if not options["show"] and options["save"]:
        plt.close(fig)
        return None
    return fig