Hi,
I needed to plot overlaid single-channel epochs for someone today (see plot below). I couldn’t figure out a clean way to do it, and ended up slicing epochs._data.
I was wondering if there is an actual API for such a plot?
Hi,
I needed to plot overlaid single-channel epochs for someone today (see plot below). I couldn’t figure out a clean way to do it, and ended up slicing epochs._data.
I was wondering if there is an actual API for such a plot?
I don’t think there’s an API for this… it might have been possible to do epochs.iter_evoked()
and then pass the result to plot_compare_evokeds
perhaps?
Do you think it’s a common enough need that it’s worth implementing one, or is this likely a one-off workflow for you? Something like plot_epochs_overlay()
with options show_epochs=bool, show_mean=bool, ci=float|bool|callable|None
(where ci
mirrors the ci
argument in plot_compare_evokeds
) seems reasonable
Thanks @drammock!
I don’t know how common this kind of plot is. Our lab has two papers in the pipeline that happen to need it. I was a bit surprised that it’s not implemented.
Of course it’s also clear that mne cannot support every possible plot out of the box. Working with _data
is fine, except for the fact that you’re working with undocumented internals and therefore the semantics are a bit unclear (e.g. does baselining directly affect _data
or not)?
To work with a documented function instead, you could use inst.get_data()
methods which has a couple of handy arguments to return only relevant parts of the underlying ._data
array.
I think baseline correction directly affects ._data
at initialization of an Epoch instance, except if baseline=None
was passed.
@mscheltienne good point about get_data()
, somehow missed it.
For the record, plot_compare_evokeds
won’t get you all the way there. Here’s how far it gets you:
import os
import mne
sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False, preload=False)
events = mne.find_events(raw, stim_channel='STI 014')
event_dict = {'auditory/left': 1}
epochs = mne.Epochs(raw, events, event_id=event_dict)
evk_list = {'aud/left': list(epochs.iter_evoked())}
mne.viz.plot_compare_evokeds(evk_list, picks=7)
(no individual traces, just the mean and CI). However, it’s not too bad using matplotlib / Seaborn:
import matplotlib.pyplot as plt
import seaborn as sns
# note: this scales grads to fT/cm by default! see `scalings` param
df = epochs.to_data_frame(picks='MEG 0133', time_format=None)
fig, ax = plt.subplots()
kwargs = dict(x='time', y='MEG 0133', data=df, ax=ax)
sns.lineplot(**kwargs, units='epoch', estimator=None, linewidth=0.5, alpha=0.2)
sns.lineplot(**kwargs, ci='sd', linewidth=2, color='r')
It needs a little tweaking to get the CI to be clearly visible against all the individual epoch traces, but even so I’m not super motivated to implement this within MNE-Python, knowing that it’s not too bad to do it manually. But I probably wouldn’t say “no” if a motivated user wanted to do the work of implementing it.