|
5 | 5 | This file contains functions for plotting power spectra, that take in data directly. |
6 | 6 | """ |
7 | 7 |
|
| 8 | +from inspect import isfunction |
8 | 9 | from itertools import repeat, cycle |
9 | 10 |
|
10 | 11 | import numpy as np |
| 12 | +from scipy.stats import sem |
11 | 13 |
|
12 | 14 | from fooof.core.modutils import safe_import, check_dependency |
13 | 15 | from fooof.plts.settings import PLT_FIGSIZES |
@@ -113,3 +115,80 @@ def plot_spectra_shading(freqs, power_spectra, shades, shade_colors='r', |
113 | 115 |
|
114 | 116 | style_spectrum_plot(ax, plot_kwargs.get('log_freqs', False), |
115 | 117 | plot_kwargs.get('log_powers', False)) |
| 118 | + |
| 119 | + |
| 120 | +@savefig |
| 121 | +@style_plot |
| 122 | +@check_dependency(plt, 'matplotlib') |
| 123 | +def plot_spectra_yshade(freqs, power_spectra, shade='std', average='mean', scale=1, |
| 124 | + log_freqs=False, log_powers=False, color=None, label=None, |
| 125 | + ax=None, **plot_kwargs): |
| 126 | + """Plot standard deviation or error as a shaded region around the mean spectrum. |
| 127 | +
|
| 128 | + Parameters |
| 129 | + ---------- |
| 130 | + freqs : 1d array |
| 131 | + Frequency values, to be plotted on the x-axis. |
| 132 | + power_spectra : 1d or 2d array |
| 133 | + Power values, to be plotted on the y-axis. ``shade`` must be provided if 1d. |
| 134 | + shade : 'std', 'sem', 1d array or callable, optional, default: 'std' |
| 135 | + Approach for shading above/below the mean spectrum. |
| 136 | + average : 'mean', 'median' or callable, optional, default: 'mean' |
| 137 | + Averaging approach for the average spectrum to plot. Only used if power_spectra is 2d. |
| 138 | + scale : int, optional, default: 1 |
| 139 | + Factor to multiply the plotted shade by. |
| 140 | + log_freqs : bool, optional, default: False |
| 141 | + Whether to plot the frequency axis in log spacing. |
| 142 | + log_powers : bool, optional, default: False |
| 143 | + Whether to plot the power axis in log spacing. |
| 144 | + color : str, optional, default: None |
| 145 | + Line color of the spectrum. |
| 146 | + label : str, optional, default: None |
| 147 | + Legend label for the spectrum. |
| 148 | + ax : matplotlib.Axes, optional |
| 149 | + Figure axes upon which to plot. |
| 150 | + **plot_kwargs |
| 151 | + Keyword arguments to be passed to `plot_spectra` or to the plot call. |
| 152 | + """ |
| 153 | + |
| 154 | + if (isinstance(shade, str) or isfunction(shade)) and power_spectra.ndim != 2: |
| 155 | + raise ValueError('Power spectra must be 2d if shade is not given.') |
| 156 | + |
| 157 | + ax = check_ax(ax, plot_kwargs.pop('figsize', PLT_FIGSIZES['spectral'])) |
| 158 | + |
| 159 | + # Set plot data & labels, logging if requested |
| 160 | + plt_freqs = np.log10(freqs) if log_freqs else freqs |
| 161 | + plt_powers = np.log10(power_spectra) if log_powers else power_spectra |
| 162 | + |
| 163 | + # Organize mean spectrum to plot |
| 164 | + avg_funcs = {'mean' : np.mean, 'median' : np.median} |
| 165 | + |
| 166 | + if isinstance(average, str) and plt_powers.ndim == 2: |
| 167 | + avg_powers = avg_funcs[average](plt_powers, axis=0) |
| 168 | + elif isfunction(average) and plt_powers.ndim == 2: |
| 169 | + avg_powers = average(plt_powers) |
| 170 | + else: |
| 171 | + avg_powers = plt_powers |
| 172 | + |
| 173 | + # Plot average power spectrum |
| 174 | + ax.plot(plt_freqs, avg_powers, linewidth=2.0, color=color, label=label) |
| 175 | + |
| 176 | + # Organize shading to plot |
| 177 | + shade_funcs = {'std' : np.std, 'sem' : sem} |
| 178 | + |
| 179 | + if isinstance(shade, str): |
| 180 | + shade_vals = scale * shade_funcs[shade](plt_powers, axis=0) |
| 181 | + elif isfunction(shade): |
| 182 | + shade_vals = scale * shade(plt_powers) |
| 183 | + else: |
| 184 | + shade_vals = scale * shade |
| 185 | + |
| 186 | + upper_shade = avg_powers + shade_vals |
| 187 | + lower_shade = avg_powers - shade_vals |
| 188 | + |
| 189 | + # Plot +/- yshading around spectrum |
| 190 | + alpha = plot_kwargs.pop('alpha', 0.25) |
| 191 | + ax.fill_between(plt_freqs, lower_shade, upper_shade, |
| 192 | + alpha=alpha, color=color, **plot_kwargs) |
| 193 | + |
| 194 | + style_spectrum_plot(ax, log_freqs, log_powers) |
0 commit comments