Skip to content

Commit 43c0304

Browse files
authored
Merge pull request #198 from fooof-tools/plts
[ENH] Combined plot_spectra and plot_spectrum
2 parents d47cbbc + 51651d3 commit 43c0304

File tree

13 files changed

+98
-164
lines changed

13 files changed

+98
-164
lines changed

doc/api.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ Plots for visualizing power spectra.
247247
.. autosummary::
248248
:toctree: generated/
249249

250-
plot_spectrum
251250
plot_spectra
252251

253252
Plots for plotting power spectra with shaded regions.
@@ -257,7 +256,6 @@ Plots for plotting power spectra with shaded regions.
257256
.. autosummary::
258257
:toctree: generated/
259258

260-
plot_spectrum_shading
261259
plot_spectra_shading
262260

263261
Plot Model Properties & Parameters

examples/analyses/plot_mne_example.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from fooof import FOOOFGroup
3333
from fooof.bands import Bands
3434
from fooof.analysis import get_band_peak_fg
35-
from fooof.plts.spectra import plot_spectrum
35+
from fooof.plts.spectra import plot_spectra
3636

3737
###################################################################################################
3838
# Load & Check MNE Data
@@ -284,10 +284,11 @@ def check_nans(data, nan_policy='zero'):
284284

285285
# Compare the power spectra between low and high exponent channels
286286
fig, ax = plt.subplots(figsize=(8, 6))
287-
plot_spectrum(fg.freqs, fg.get_fooof(np.argmin(exps)).power_spectrum,
288-
ax=ax, label='Low Exponent')
289-
plot_spectrum(fg.freqs, fg.get_fooof(np.argmax(exps)).power_spectrum,
290-
ax=ax, label='High Exponent')
287+
288+
spectra = [fg.get_fooof(np.argmin(exps)).power_spectrum,
289+
fg.get_fooof(np.argmax(exps)).power_spectrum]
290+
291+
plot_spectra(fg.freqs, spectra, ax=ax, labels=['Low Exponent', 'High Exponent'])
291292

292293
###################################################################################################
293294
# Conclusion

examples/plots/plot_power_spectra.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
import matplotlib.pyplot as plt
1212

1313
# Import plotting functions
14-
from fooof.plts.spectra import plot_spectrum, plot_spectra
15-
from fooof.plts.spectra import plot_spectrum_shading, plot_spectra_shading
14+
from fooof.plts.spectra import plot_spectra, plot_spectra_shading
1615

1716
# Import simulation utilities for creating test data
1817
from fooof.sim.gen import gen_power_spectrum, gen_group_power_spectra
@@ -59,7 +58,7 @@
5958
#
6059
# First we will start with the core plotting function that plots an individual power spectrum.
6160
#
62-
# The :func:`~.plot_spectrum` function takes in an array of frequency values and a 1d array of
61+
# The :func:`~.plot_spectra` function takes in an array of frequency values and a 1d array of
6362
# of power values, and plots the corresponding power spectrum.
6463
#
6564
# This function, as all the functions in the plotting module, takes in optional inputs
@@ -70,7 +69,7 @@
7069
###################################################################################################
7170

7271
# Create a spectrum plot with a single power spectrum
73-
plot_spectrum(freqs, powers1, log_powers=True)
72+
plot_spectra(freqs, powers1, log_powers=True)
7473

7574
###################################################################################################
7675
# Plotting Multiple Power Spectra
@@ -97,7 +96,7 @@
9796
# In some cases it may be useful to highlight or shade in particular frequency regions,
9897
# for example, when examining power in particular frequency regions.
9998
#
100-
# The :func:`~.plot_spectrum_shading` function takes in a power spectrum and one or more
99+
# The :func:`~.plot_spectra_shading` function takes in a power spectrum and one or more
101100
# shaded regions, and plot the power spectrum with the indicated region shaded.
102101
#
103102
# The same can be done for multiple power spectra with :func:`~.plot_spectra_shading`.
@@ -110,7 +109,7 @@
110109
###################################################################################################
111110

112111
# Plot a single power spectrum, with a shaded region covering alpha
113-
plot_spectrum_shading(freqs, powers1, [8, 12], log_powers=True)
112+
plot_spectra_shading(freqs, powers1, [8, 12], log_powers=True)
114113

115114
###################################################################################################
116115

@@ -157,6 +156,6 @@
157156
fig, ax = plt.subplots(figsize=[12, 8])
158157
plot_spectra_shading(freqs_al, powers_al, [8, 12],
159158
log_powers=True, alpha=0.6, ax=ax)
160-
plot_spectrum(freqs_al10, powers_al10, log_powers=True,
161-
color='black', linewidth=3, label='10 Hz Alpha', ax=ax)
159+
plot_spectra(freqs_al10, powers_al10, log_powers=True,
160+
color='black', linewidth=3, label='10 Hz Alpha', ax=ax)
162161
plt.title('Comparing Alphas', {'fontsize' : 20, 'fontweight' : 'bold'});

examples/sims/plot_simulated_power_spectra.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from fooof.sim.gen import gen_power_spectrum, gen_group_power_spectra
1212

1313
# Import plotting functions
14-
from fooof.plts.spectra import plot_spectrum, plot_spectra
14+
from fooof.plts.spectra import plot_spectra
1515

1616
###################################################################################################
1717
# Creating Simulated Power Spectra
@@ -53,7 +53,7 @@
5353
###################################################################################################
5454

5555
# Plot the simulated power spectrum
56-
plot_spectrum(freqs, powers, log_freqs=True, log_powers=False)
56+
plot_spectra(freqs, powers, log_freqs=True, log_powers=False)
5757

5858
###################################################################################################
5959
# Simulating With Different Parameters
@@ -100,7 +100,7 @@
100100
###################################################################################################
101101

102102
# Plot the new simulated power spectrum
103-
plot_spectrum(freqs, powers, log_powers=True)
103+
plot_spectra(freqs, powers, log_powers=True)
104104

105105
###################################################################################################
106106
# Simulating a Group of Power Spectra

fooof/plts/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
"""Plots sub-module for FOOOF."""
22

3-
from .spectra import plot_spectrum, plot_spectra
3+
from .spectra import plot_spectra
4+
from .spectra import plot_spectra as plot_spectrum

fooof/plts/annotate.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
from fooof.core.errors import NoModelError
77
from fooof.core.funcs import gaussian_function
88
from fooof.core.modutils import safe_import, check_dependency
9+
910
from fooof.sim.gen import gen_aperiodic
11+
from fooof.analysis.periodic import get_band_peak_fm
12+
from fooof.utils.params import compute_knee_frequency, compute_fwhm
13+
14+
from fooof.plts.spectra import plot_spectra
1015
from fooof.plts.utils import check_ax, savefig
11-
from fooof.plts.spectra import plot_spectrum
1216
from fooof.plts.settings import PLT_FIGSIZES, PLT_COLORS
1317
from fooof.plts.style import style_spectrum_plot
14-
from fooof.analysis.periodic import get_band_peak_fm
15-
from fooof.utils.params import compute_knee_frequency, compute_fwhm
1618

1719
plt = safe_import('.pyplot', 'matplotlib')
1820
mpatches = safe_import('.patches', 'matplotlib')
@@ -45,12 +47,12 @@ def plot_annotated_peak_search(fm):
4547
# This forces the creation of a new plotting axes per iteration
4648
ax = check_ax(None, PLT_FIGSIZES['spectral'])
4749

48-
plot_spectrum(fm.freqs, flatspec, ax=ax, linewidth=2.5,
49-
label='Flattened Spectrum', color=PLT_COLORS['data'])
50-
plot_spectrum(fm.freqs, [fm.peak_threshold * np.std(flatspec)]*len(fm.freqs), ax=ax,
51-
label='Relative Threshold', color='orange', linewidth=2.5, linestyle='dashed')
52-
plot_spectrum(fm.freqs, [fm.min_peak_height]*len(fm.freqs), ax=ax,
53-
label='Absolute Threshold', color='red', linewidth=2.5, linestyle='dashed')
50+
plot_spectra(fm.freqs, flatspec, ax=ax, linewidth=2.5,
51+
label='Flattened Spectrum', color=PLT_COLORS['data'])
52+
plot_spectra(fm.freqs, [fm.peak_threshold * np.std(flatspec)]*len(fm.freqs), ax=ax,
53+
label='Relative Threshold', color='orange', linewidth=2.5, linestyle='dashed')
54+
plot_spectra(fm.freqs, [fm.min_peak_height]*len(fm.freqs), ax=ax,
55+
label='Absolute Threshold', color='red', linewidth=2.5, linestyle='dashed')
5456

5557
maxi = np.argmax(flatspec)
5658
ax.plot(fm.freqs[maxi], flatspec[maxi], '.',
@@ -62,8 +64,8 @@ def plot_annotated_peak_search(fm):
6264
if ind < fm.n_peaks_:
6365

6466
gauss = gaussian_function(fm.freqs, *fm.gaussian_params_[ind, :])
65-
plot_spectrum(fm.freqs, gauss, ax=ax, label='Gaussian Fit',
66-
color=PLT_COLORS['periodic'], linestyle=':', linewidth=3.0)
67+
plot_spectra(fm.freqs, gauss, ax=ax, label='Gaussian Fit',
68+
color=PLT_COLORS['periodic'], linestyle=':', linewidth=3.0)
6769

6870
flatspec = flatspec - gauss
6971

fooof/plts/error.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy as np
44

55
from fooof.core.modutils import safe_import, check_dependency
6-
from fooof.plts.spectra import plot_spectrum
6+
from fooof.plts.spectra import plot_spectra
77
from fooof.plts.settings import PLT_FIGSIZES
88
from fooof.plts.style import style_spectrum_plot, style_plot
99
from fooof.plts.utils import check_ax, savefig
@@ -40,7 +40,7 @@ def plot_spectral_error(freqs, error, shade=None, log_freqs=False, ax=None, **pl
4040

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

43-
plot_spectrum(plt_freqs, error, ax=ax, linewidth=3)
43+
plot_spectra(plt_freqs, error, ax=ax, linewidth=3)
4444

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

fooof/plts/fm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from fooof.sim.gen import gen_periodic
1313
from fooof.utils.data import trim_spectrum
1414
from fooof.utils.params import compute_fwhm
15-
from fooof.plts.spectra import plot_spectrum
15+
from fooof.plts.spectra import plot_spectra
1616
from fooof.plts.settings import PLT_FIGSIZES, PLT_COLORS
1717
from fooof.plts.utils import check_ax, check_plot_kwargs, savefig
1818
from fooof.plts.style import style_spectrum_plot, style_plot
@@ -73,22 +73,22 @@ def plot_fm(fm, plot_peaks=None, plot_aperiodic=True, plt_log=False, add_legend=
7373
data_defaults = {'color' : PLT_COLORS['data'], 'linewidth' : 2.0,
7474
'label' : 'Original Spectrum' if add_legend else None}
7575
data_kwargs = check_plot_kwargs(data_kwargs, data_defaults)
76-
plot_spectrum(fm.freqs, fm.power_spectrum, log_freqs, log_powers, ax=ax, **data_kwargs)
76+
plot_spectra(fm.freqs, fm.power_spectrum, log_freqs, log_powers, ax=ax, **data_kwargs)
7777

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

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

9393
# Plot the periodic components of the model fit
9494
if plot_peaks:

fooof/plts/spectra.py

Lines changed: 27 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -12,73 +12,34 @@
1212
from fooof.core.modutils import safe_import, check_dependency
1313
from fooof.plts.settings import PLT_FIGSIZES
1414
from fooof.plts.style import style_spectrum_plot, style_plot
15-
from fooof.plts.utils import check_ax, add_shades, savefig
15+
from fooof.plts.utils import check_ax, add_shades, savefig, check_plot_kwargs
1616

1717
plt = safe_import('.pyplot', 'matplotlib')
1818

1919
###################################################################################################
2020
###################################################################################################
2121

22-
@savefig
23-
@style_plot
24-
@check_dependency(plt, 'matplotlib')
25-
def plot_spectrum(freqs, power_spectrum, log_freqs=False, log_powers=False,
26-
color=None, label=None, ax=None, **plot_kwargs):
27-
"""Plot a power spectrum.
28-
29-
Parameters
30-
----------
31-
freqs : 1d array
32-
Frequency values, to be plotted on the x-axis.
33-
power_spectrum : 1d array
34-
Power values, to be plotted on the y-axis.
35-
log_freqs : bool, optional, default: False
36-
Whether to plot the frequency axis in log spacing.
37-
log_powers : bool, optional, default: False
38-
Whether to plot the power axis in log spacing.
39-
label : str, optional, default: None
40-
Legend label for the spectrum.
41-
color : str, optional, default: None
42-
Line color of the spectrum.
43-
ax : matplotlib.Axes, optional
44-
Figure axis upon which to plot.
45-
**plot_kwargs
46-
Keyword arguments to pass into the ``style_plot``.
47-
"""
48-
49-
ax = check_ax(ax, plot_kwargs.pop('figsize', PLT_FIGSIZES['spectral']))
50-
51-
# Set plot data & labels, logging if requested
52-
plt_freqs = np.log10(freqs) if log_freqs else freqs
53-
plt_powers = np.log10(power_spectrum) if log_powers else power_spectrum
54-
55-
# Create the plot
56-
ax.plot(plt_freqs, plt_powers, linewidth=2.0, color=color, label=label)
57-
58-
style_spectrum_plot(ax, log_freqs, log_powers)
59-
60-
6122
@savefig
6223
@style_plot
6324
@check_dependency(plt, 'matplotlib')
6425
def plot_spectra(freqs, power_spectra, log_freqs=False, log_powers=False,
6526
colors=None, labels=None, ax=None, **plot_kwargs):
66-
"""Plot multiple power spectra on the same plot.
27+
"""Plot one or multiple power spectra.
6728
6829
Parameters
6930
----------
70-
freqs : 2d array or 1d array or list of 1d array
31+
freqs : 1d or 2d array or list of 1d array
7132
Frequency values, to be plotted on the x-axis.
72-
power_spectra : 2d array or list of 1d array
33+
power_spectra : 1d or 2d array or list of 1d array
7334
Power values, to be plotted on the y-axis.
7435
log_freqs : bool, optional, default: False
7536
Whether to plot the frequency axis in log spacing.
7637
log_powers : bool, optional, default: False
7738
Whether to plot the power axis in log spacing.
78-
labels : list of str, optional, default: None
79-
Legend labels for the spectra.
8039
colors : list of str, optional, default: None
8140
Line colors of the spectra.
41+
labels : list of str, optional, default: None
42+
Legend labels for the spectra.
8243
ax : matplotlib.Axes, optional
8344
Figure axes upon which to plot.
8445
**plot_kwargs
@@ -87,64 +48,44 @@ def plot_spectra(freqs, power_spectra, log_freqs=False, log_powers=False,
8748

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

51+
# Create the plot
52+
plot_kwargs = check_plot_kwargs(plot_kwargs, {'linewidth' : 2.0})
53+
9054
# Make inputs iterable if need to be passed multiple times to plot each spectrum
91-
freqs = repeat(freqs) if isinstance(freqs, np.ndarray) and freqs.ndim == 1 else freqs
55+
plt_powers = np.reshape(power_spectra, (1, -1)) if np.ndim(power_spectra) == 1 else \
56+
power_spectra
57+
plt_freqs = repeat(freqs) if isinstance(freqs, np.ndarray) and freqs.ndim == 1 else freqs
9258

93-
colors = repeat(colors) if not isinstance(colors, list) else cycle(colors)
59+
# Set labels
60+
labels = plot_kwargs.pop('label') if 'label' in plot_kwargs.keys() and labels is None else labels
9461
labels = repeat(labels) if not isinstance(labels, list) else cycle(labels)
62+
colors = repeat(colors) if not isinstance(colors, list) else cycle(colors)
9563

96-
for freq, power_spectrum, color, label in zip(freqs, power_spectra, colors, labels):
97-
plot_spectrum(freq, power_spectrum, log_freqs, log_powers,
98-
color=color, label=label, ax=ax)
99-
100-
style_spectrum_plot(ax, log_freqs, log_powers)
101-
102-
103-
@savefig
104-
@check_dependency(plt, 'matplotlib')
105-
def plot_spectrum_shading(freqs, power_spectrum, shades, shade_colors='r',
106-
add_center=False, ax=None, **plot_kwargs):
107-
"""Plot a power spectrum with a shaded frequency region (or regions).
108-
109-
Parameters
110-
----------
111-
freqs : 1d array
112-
Frequency values, to be plotted on the x-axis.
113-
power_spectrum : 1d array
114-
Power values, to be plotted on the y-axis.
115-
shades : list of [float, float] or list of list of [float, float]
116-
Shaded region(s) to add to plot, defined as [lower_bound, upper_bound].
117-
shade_colors : str or list of string
118-
Color(s) to plot shades.
119-
add_center : bool, optional, default: False
120-
Whether to add a line at the center point of the shaded regions.
121-
ax : matplotlib.Axes, optional
122-
Figure axes upon which to plot.
123-
**plot_kwargs
124-
Keyword arguments to pass into :func:`~.plot_spectrum`.
125-
"""
126-
127-
ax = check_ax(ax, plot_kwargs.pop('figsize', PLT_FIGSIZES['spectral']))
64+
# Plot
65+
for freqs, powers, color, label in zip(plt_freqs, plt_powers, colors, labels):
12866

129-
plot_spectrum(freqs, power_spectrum, ax=ax, **plot_kwargs)
67+
# Set plot data, logging if requested, and collect color, if absent
68+
freqs = np.log10(freqs) if log_freqs else freqs
69+
powers = np.log10(powers) if log_powers else powers
70+
if color:
71+
plot_kwargs['color'] = color
13072

131-
add_shades(ax, shades, shade_colors, add_center, plot_kwargs.get('log_freqs', False))
73+
ax.plot(freqs, powers, label=label, **plot_kwargs)
13274

133-
style_spectrum_plot(ax, plot_kwargs.get('log_freqs', False),
134-
plot_kwargs.get('log_powers', False))
75+
style_spectrum_plot(ax, log_freqs, log_powers)
13576

13677

13778
@savefig
13879
@check_dependency(plt, 'matplotlib')
13980
def plot_spectra_shading(freqs, power_spectra, shades, shade_colors='r',
14081
add_center=False, ax=None, **plot_kwargs):
141-
"""Plot a group of power spectra with a shaded frequency region (or regions).
82+
"""Plot one or multiple power spectra with a shaded frequency region (or regions).
14283
14384
Parameters
14485
----------
145-
freqs : 2d array or 1d array or list of 1d array
86+
freqs : 1d or 2d array or list of 1d array
14687
Frequency values, to be plotted on the x-axis.
147-
power_spectra : 2d array or list of 1d array
88+
power_spectra : 1d or 2d array or list of 1d array
14889
Power values, to be plotted on the y-axis.
14990
shades : list of [float, float] or list of list of [float, float]
15091
Shaded region(s) to add to plot, defined as [lower_bound, upper_bound].

0 commit comments

Comments
 (0)