mne-python
mne-python copied to clipboard
Enh browserfig UI events
What does this implement/fix?
Creates hook to use UI-events in the Qt browser. Also implements the TimeChange event for the matplotlib-based browser.
Additional information
This needs a unit test.
Now the following works:
import mne
path = mne.datasets.sample.data_path()
raw = mne.io.read_raw_fif(path / "MEG/sample/sample_audvis_raw.fif", preload=True)
mne.viz.set_browser_backend("matplotlib")
fig1 = raw.copy().pick("eeg").plot()
fig2 = raw.copy().pick("meg").plot()
mne.viz.ui_events.link(fig1, fig2)
And scrolling through time will update both figures.
@wmvanvliet I added the ChannelBrowse and TimeBrowse ui events. Just need to make unit tests for them
This needs a unit test.
Where/how would I put a unit test? I also saw there's no unit test for Brain and EvokedField objects. Do those need unit tests as well?
@wmvanvliet the matplotlib and qt browsers (on this branch https://github.com/mne-tools/mne-qt-browser/pull/286 ) are synced in time and channels. It's also working for epochs.
I've overhauled the event code in the matplotlib figure a bit. The biggest improvement is that now the TimeBrowse event generates meaningful time_start and time_end values. So if you open a raw browser and an epochs browser side-by-side, you can link the event streams and have their scrolling behavior synced. Try this out:
import mne
path = mne.datasets.sample.data_path()
raw = mne.io.read_raw_fif(path / "MEG" / "sample" / "sample_audvis_raw.fif")
events = mne.find_events(raw)
epochs = mne.Epochs(raw, events, preload=True)
mne.viz.set_browser_backend('matplotlib')
fig1 = raw.plot(events=events)
fig2 = epochs.plot()
def on_time_browse_event(event):
print(event)
def on_channel_browse_event(event):
print(event)
def on_time_change_event(event):
print(event)
mne.viz.ui_events.subscribe(fig2, 'time_browse', on_time_browse_event)
mne.viz.ui_events.subscribe(fig2, 'channel_browse', on_channel_browse_event)
mne.viz.ui_events.subscribe(fig2, 'time_change', on_time_change_event)
mne.viz.ui_events.link(fig2, fig1, include_events=['time_browse', 'channel_browse'])
another improvement is that the figure is no longer updated twice on every keypress. Before, the keypress first updated the figure and then generated the UI event, which caused the event handler to update the figure again. Now, the keypress just generates the UI event and lets the event handler take care of updating the figure.
Should we do the same for the vertical bar? Currently when the vertical bar appears in epoch mode all epochs at that timepoint are marked with a vertical bar. So raw time doesn't matter here.
I've updated the TimeChange event (the vertical bar) to properly indicate the time in the epoch (from tmin to tmax instead of from 0 to epoch duration)
@wmvanvliet @drammock I need to finish this branch and pull this before I can pull https://github.com/mne-tools/mne-qt-browser/pull/286 . Currently there's a bug when changing channels that results in incorrect labels
Currently there's a bug when changing channels that results in incorrect labels
So this is a point at which I would start adding stuff like this to the code:
logger.debug(f"Channel change event received by {self}: {ch_names[0]=} {ch_names[-1]=}")
and similarly for "Channel change event emitted by ..." etc. Then you should see in code something that looks correct, but then the labeling be incorrect or so. Then you can add a logger.debug statement where the channels are actually relabeled in the matplotlib browser code, etc.
EDIT: And you'll need to use a mne.set_log_level("debug") to see the messages