コード例 #1
0
ファイル: error.py プロジェクト: parhalje/fooof
def plot_spectral_error(freqs,
                        error,
                        shade=None,
                        log_freqs=False,
                        ax=None,
                        **plot_kwargs):
    """Plot frequency by frequency error values.

    Parameters
    ----------
    freqs : 1d array
        Frequency values, to be plotted on the x-axis.
    error : 1d array
        Calculated error values or mean error values across frequencies, to plot on the y-axis.
    shade : 1d array, optional
        Values to shade in around the plotted error.
        This could be, for example, the standard deviation of the errors.
    log_freqs : bool, optional, default: False
        Whether to plot the frequency axis in log spacing.
    ax : matplotlib.Axes, optional
        Figure axes upon which to plot.
    **plot_kwargs
        Keyword arguments to pass into the ``style_plot``.
    """

    ax = check_ax(ax, plot_kwargs.pop('figsize', PLT_FIGSIZES['spectral']))

    plt_freqs = np.log10(freqs) if log_freqs else freqs

    plot_spectra(plt_freqs, error, ax=ax, linewidth=3)

    if np.any(shade):
        ax.fill_between(plt_freqs, error - shade, error + shade, alpha=0.25)

    ymin, ymax = ax.get_ylim()
    if ymin < 0:
        ax.set_ylim([0, ymax])
    ax.set_xlim(plt_freqs.min(), plt_freqs.max())

    style_spectrum_plot(ax, log_freqs, True)
    ax.set_ylabel('Absolute Error')
コード例 #2
0
# Aperiodic params: define values for each spectrum, with length equal to n_spectra
aperiodic_params = [[0.5, 1], [1, 1.5]]

# Periodic parameters: define a single definition, to be applied to all spectra
periodic_params = [10, 0.4, 1]

###################################################################################################

# Simulate a group of power spectra
freqs, powers = gen_group_power_spectra(n_spectra, freq_range,
                                        aperiodic_params, periodic_params, nlv)

###################################################################################################

# Plot the power spectra that were just generated
plot_spectra(freqs, powers, log_freqs=True, log_powers=True)

###################################################################################################
# Tracking Simulation Parameters
# ------------------------------
#
# When you start simulating multiple power spectra across different parameters,
# you may want to keep track of these parameters, so that you can compare any measure
# taken on these power spectra to ground truth values.
#
# When simulating power spectra, you also have the option of returning SimParams objects
# that keep track of the simulation parameters.
#

###################################################################################################
コード例 #3
0
ファイル: plot_transforms.py プロジェクト: eackermann/fooof
# Imports
from fooof.synth.gen import gen_power_spectrum
from fooof.synth.transform import rotate_spectrum

from fooof.plts.spectra import plot_spectra

###################################################################################################

# Generate a synthetic power spectrum
fs, ps = gen_power_spectrum([3, 40], [1, 1], [10, 0.5, 1])

###################################################################################################
# rotate_spectrum
# ---------------
#
# The :func:`rotate_spectrum` function takes in a power spectrum, and rotates the
# power spectrum a specified amount, around a specified frequency point, changing
# the aperiodic exponent of the spectrum.
#

###################################################################################################

# Rotate the power spectrum
nps = rotate_spectrum(fs, ps, 0.25, 20)

###################################################################################################

# Plot the two power spectra
plot_spectra(fs, [ps, nps], log_freqs=True, log_powers=True)
コード例 #4
0
# ---------------------------------
#
# First we will start with the core plotting function that plots an individual power spectrum.
#
# The :func:`~.plot_spectra` function takes in an array of frequency values and a 1d array of
# of power values, and plots the corresponding power spectrum.
#
# This function, as all the functions in the plotting module, takes in optional inputs
# `log_freqs` and `log_powers` that control whether the frequency and power axes
# are plotted in log space.
#

###################################################################################################

# Create a spectrum plot with a single power spectrum
plot_spectra(freqs, powers1, log_powers=True)

###################################################################################################
# Plotting Multiple Power Spectra
# -------------------------------
#
# The :func:`~.plot_spectra` function takes in one or more frequency arrays and one or more
# array of associated power values and plots multiple power spectra.
#
# Note that the inputs for either can be either 2d arrays, or lists of 1d arrays. You can also
# pass in additional optional inputs including `labels`, to specify labels to use in a plot
# legend, and `colors` to specify which colors to plot each spectrum in.
#

###################################################################################################
コード例 #5
0
ファイル: fm.py プロジェクト: parhalje/fooof
def plot_fm(fm,
            plot_peaks=None,
            plot_aperiodic=True,
            plt_log=False,
            add_legend=True,
            save_fig=False,
            file_name=None,
            file_path=None,
            ax=None,
            data_kwargs=None,
            model_kwargs=None,
            aperiodic_kwargs=None,
            peak_kwargs=None,
            **plot_kwargs):
    """Plot the power spectrum and model fit results from a FOOOF object.

    Parameters
    ----------
    fm : FOOOF
        Object containing a power spectrum and (optionally) results from fitting.
    plot_peaks : None or {'shade', 'dot', 'outline', 'line'}, optional
        What kind of approach to take to plot peaks. If None, peaks are not specifically plotted.
        Can also be a combination of approaches, separated by '-', for example: 'shade-line'.
    plot_aperiodic : boolean, optional, default: True
        Whether to plot the aperiodic component of the model fit.
    plt_log : boolean, optional, default: False
        Whether to plot the frequency values in log10 spacing.
    add_legend : boolean, optional, default: False
        Whether to add a legend describing the plot components.
    save_fig : bool, optional, default: False
        Whether to save out a copy of the plot.
    file_name : str, optional
        Name to give the saved out file.
    file_path : str, optional
        Path to directory to save to. If None, saves to current directory.
    ax : matplotlib.Axes, optional
        Figure axes upon which to plot.
    data_kwargs, model_kwargs, aperiodic_kwargs, peak_kwargs : None or dict, optional
        Keyword arguments to pass into the plot call for each plot element.
    **plot_kwargs
        Keyword arguments to pass into the ``style_plot``.

    Notes
    -----
    Since FOOOF objects store power values in log spacing,
    the y-axis (power) is plotted in log spacing by default.
    """

    ax = check_ax(ax, PLT_FIGSIZES['spectral'])

    # Log settings - note that power values in FOOOF objects are already logged
    log_freqs = plt_log
    log_powers = False

    # Plot the data, if available
    if fm.has_data:
        data_defaults = {
            'color': PLT_COLORS['data'],
            'linewidth': 2.0,
            'label': 'Original Spectrum' if add_legend else None
        }
        data_kwargs = check_plot_kwargs(data_kwargs, data_defaults)
        plot_spectra(fm.freqs,
                     fm.power_spectrum,
                     log_freqs,
                     log_powers,
                     ax=ax,
                     **data_kwargs)

    # Add the full model fit, and components (if requested)
    if fm.has_model:
        model_defaults = {
            'color': PLT_COLORS['model'],
            'linewidth': 3.0,
            'alpha': 0.5,
            'label': 'Full Model Fit' if add_legend else None
        }
        model_kwargs = check_plot_kwargs(model_kwargs, model_defaults)
        plot_spectra(fm.freqs,
                     fm.fooofed_spectrum_,
                     log_freqs,
                     log_powers,
                     ax=ax,
                     **model_kwargs)

        # Plot the aperiodic component of the model fit
        if plot_aperiodic:
            aperiodic_defaults = {
                'color': PLT_COLORS['aperiodic'],
                'linewidth': 3.0,
                'alpha': 0.5,
                'linestyle': 'dashed',
                'label': 'Aperiodic Fit' if add_legend else None
            }
            aperiodic_kwargs = check_plot_kwargs(aperiodic_kwargs,
                                                 aperiodic_defaults)
            plot_spectra(fm.freqs,
                         fm._ap_fit,
                         log_freqs,
                         log_powers,
                         ax=ax,
                         **aperiodic_kwargs)

        # Plot the periodic components of the model fit
        if plot_peaks:
            _add_peaks(fm, plot_peaks, plt_log, ax, peak_kwargs)

    # Apply default style to plot
    style_spectrum_plot(ax, log_freqs, True)
コード例 #6
0
# Step 1: Initial Aperiodic Fit
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# We start by taking an initial aperiodic fit. This goal of this fit is to get an initial
# fit that is good enough to get started with the fitting process.
#

###################################################################################################

# Do an initial aperiodic fit - a robust fit, that excludes outliers
#   This recreates an initial fit that isn't ultimately stored in the FOOOF object
init_ap_fit = gen_aperiodic(fm.freqs, fm._robust_ap_fit(fm.freqs, fm.power_spectrum))

# Plot the initial aperiodic fit
_, ax = plt.subplots(figsize=(12, 10))
plot_spectra(fm.freqs, fm.power_spectrum, plt_log,
             label='Original Power Spectrum', color='black', ax=ax)
plot_spectra(fm.freqs, init_ap_fit, plt_log, label='Initial Aperiodic Fit',
             color='blue', alpha=0.5, linestyle='dashed', ax=ax)

###################################################################################################
# Step 2: Flatten the Spectrum
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# The initial fit is then used to create a flattened spectrum.
#
# The initial aperiodic fit is subtracted out from the original data, leaving a flattened
# version of the data which no longer contains the aperiodic component.
#

###################################################################################################
コード例 #7
0
# -------------------------------
#
# The :func:`~.plot_spectra` function takes in one or more frequency arrays and one or more
# array of associated power values and plots multiple power spectra.
#
# Note that the inputs for either can be either 2d arrays, or lists of 1d arrays. You can also
# pass in additional optional inputs including `labels`, to specify labels to use in a plot
# legend, and `colors` to specify which colors to plot each spectrum in.
#

###################################################################################################

# Plot multiple spectra on the same plot, in log-log space, specifying some labels
labels = ['PSD-1', 'PSD-2']
plot_spectra(freqs, [powers1, powers2],
             log_freqs=True,
             log_powers=True,
             labels=labels)

###################################################################################################
# Plots With Shaded Regions
# -------------------------
#
# In some cases it may be useful to highlight or shade in particular frequency regions,
# for example, when examining power in particular frequency regions.
#
# The :func:`~.plot_spectrum_shading` function takes in a power spectrum and one or more
# shaded regions, and plot the power spectrum with the indicated region shaded.
#
# The same can be done for multiple power spectra with :func:`~.plot_spectra_shading`.
#
# These functions take in an input designating one or more shade regions, each specified
コード例 #8
0
ファイル: plot_synth_params.py プロジェクト: eackermann/fooof
# Create a sampler to choose from two options for aperiodic parameters
ap_opts = param_sampler([[1, 1.25], [1, 1]])

# Create sampler to choose from two options for periodic parameters, and specify probabilities
gauss_opts = param_sampler([[10, 0.5, 1], [[10, 0.5, 1], [20, 0.25, 2]]],
                           [0.75, 0.25])

###################################################################################################

# Generate some power spectra, using the param samplers
fs, ps, syn_params = gen_group_power_spectra(10, [3, 40], ap_opts, gauss_opts)

###################################################################################################

# Plot some of the spectra that were generated
plot_spectra(fs, ps[0:4, :], log_powers=True)

###################################################################################################
# param_iter
# ~~~~~~~~~~
#
# The :func:`param_iter` function can be used to create iterators that can 'step' across
# a range of parameter values to be simulated.
#
# The :class:`Stepper` object needs to be used in conjuction with :func:`param_iter`,
# as it specifies the values to be iterated across.
#

###################################################################################################

# Set the aperiodic parameters to be stable
コード例 #9
0
#
# Plotted below is an example power spectrum, plotted in semi-log space (log10 power values
# and linear frequencies). This is our data, that we will be trying to model.
#
# In the plot, we see a power spectrum in which there is decreasing power across increasing
# frequencies. In some frequency regions, there is a 'peak' of power, over and above the general
# trend across frequencies. These properties - a pattern of decreasing power across frequencies,
# with overlying peaks - are considered to be hallmarks of neural field data.
#

###################################################################################################

# Plot one of the example power spectra
plot_spectra(freqs1,
             powers1,
             log_powers=True,
             color='black',
             label='Original Spectrum')

###################################################################################################
# Conceptual Overview
# -------------------
#
# The goal of this module is to fit models to parameterize neural power spectra.
#
# One reason to do so is the idea that there are multiple distinct 'components' within
# neural field data. The model is therefore designed to measure these different
# 'components' of the data.
#
# By components, we mean that we are going to conceptualize neural field data as consisting
# of a combination of periodic (oscillatory) and aperiodic activity. Restated, we could say
コード例 #10
0
def plot_annotated_peak_search(fm):
    """Plot a series of plots illustrating the peak search from a flattened spectrum.

    Parameters
    ----------
    fm : FOOOF
        FOOOF object, with model fit, data and settings available.
    """

    # Recalculate the initial aperiodic fit and flattened spectrum that
    #   is the same as the one that is used in the peak fitting procedure
    flatspec = fm.power_spectrum - \
        gen_aperiodic(fm.freqs, fm._robust_ap_fit(fm.freqs, fm.power_spectrum))

    # Calculate ylims of the plot that are scaled to the range of the data
    ylims = [
        min(flatspec) - 0.1 * np.abs(min(flatspec)),
        max(flatspec) + 0.1 * max(flatspec)
    ]

    # Loop through the iterative search for each peak
    for ind in range(fm.n_peaks_ + 1):

        # This forces the creation of a new plotting axes per iteration
        ax = check_ax(None, PLT_FIGSIZES['spectral'])

        plot_spectra(fm.freqs,
                     flatspec,
                     ax=ax,
                     linewidth=2.5,
                     label='Flattened Spectrum',
                     color=PLT_COLORS['data'])
        plot_spectra(fm.freqs,
                     [fm.peak_threshold * np.std(flatspec)] * len(fm.freqs),
                     ax=ax,
                     label='Relative Threshold',
                     color='orange',
                     linewidth=2.5,
                     linestyle='dashed')
        plot_spectra(fm.freqs, [fm.min_peak_height] * len(fm.freqs),
                     ax=ax,
                     label='Absolute Threshold',
                     color='red',
                     linewidth=2.5,
                     linestyle='dashed')

        maxi = np.argmax(flatspec)
        ax.plot(fm.freqs[maxi],
                flatspec[maxi],
                '.',
                color=PLT_COLORS['periodic'],
                alpha=0.75,
                markersize=30)

        ax.set_ylim(ylims)
        ax.set_title('Iteration #' + str(ind + 1), fontsize=16)

        if ind < fm.n_peaks_:

            gauss = gaussian_function(fm.freqs, *fm.gaussian_params_[ind, :])
            plot_spectra(fm.freqs,
                         gauss,
                         ax=ax,
                         label='Gaussian Fit',
                         color=PLT_COLORS['periodic'],
                         linestyle=':',
                         linewidth=3.0)

            flatspec = flatspec - gauss

        style_spectrum_plot(ax, False, True)
コード例 #11
0
ファイル: plot_transforms.py プロジェクト: ryanhammonds/fooof
# changing the aperiodic exponent of the spectrum.
#

###################################################################################################

# Rotation settings
delta_exp = 0.25        # How much to change the exponent by
f_rotation = 20         # The frequency at which to rotate the spectrum

# Rotate the power spectrum
r_powers = rotate_spectrum(freqs, powers, delta_exp, f_rotation)

###################################################################################################

# Plot the two power spectra, with the rotation applied
plot_spectra(freqs, [powers, r_powers], log_freqs=True, log_powers=True)

###################################################################################################
#
# Next, we can fit power spectrum models to check if our change in exponent worked as expected.
#

###################################################################################################

# Initialize FOOOF objects
fm1 = FOOOF(verbose=False)
fm2 = FOOOF(verbose=False)

# Fit power spectrum models to the original, and rotated, spectrum
fm1.fit(freqs, powers)
fm2.fit(freqs, r_powers)
コード例 #12
0
#
# To visualize how much the exponent values vary, we can again plot some example power
# spectra, in this case extracting those with the highest and lower exponent values.
#

###################################################################################################

# Compare the power spectra between low and high exponent channels
fig, ax = plt.subplots(figsize=(8, 6))

spectra = [
    fg.get_fooof(np.argmin(exps)).power_spectrum,
    fg.get_fooof(np.argmax(exps)).power_spectrum
]

plot_spectra(fg.freqs,
             spectra,
             ax=ax,
             labels=['Low Exponent', 'High Exponent'])

###################################################################################################
# Conclusion
# ----------
#
# In this example, we have seen how to apply power spectrum models to data that is
# managed and processed with MNE.
#

###################################################################################################
#