mne-python icon indicating copy to clipboard operation
mne-python copied to clipboard

TimeChange, TimeBrowse, ChannelBrowse in ui-event system

Open nmarkowitz opened this issue 1 year ago • 5 comments

Describe the new feature or enhancement

Create new UIEvent subclasses and update functions to handle when figures on the event system change:

  • time (discretely) - TimeChange
  • time (range/span) - TimeBrowse
  • channel - ChannelBrowse

All three different events could be experienced in the databrowser (MNE or Qt)

Describe your proposed implementation

Create new classes: TimeBrowse and ChannelBrowse to enable figures and databrowsers to update depending on the type of change

Describe possible alternatives

NA

Additional context

PR for adding TimeBrowse and ChannelBrowse ui events https://github.com/mne-tools/mne-python/pull/12819

nmarkowitz avatar Aug 29 '24 17:08 nmarkowitz

@wmvanvliet I created this issue due to the large number of ideas we discussed earlier. We can list PRs here and come up with a step-by-step plan

nmarkowitz avatar Aug 29 '24 17:08 nmarkowitz

To add some context; we would like to:

  1. Link two browser windows together so that scrolling through time in one of them will also scroll the second one.
  2. Link a topomap or Brain figure with a browser window. If you select a time in the browser window (vertical line appears), the topomap/Brain updates to reflect that time.

Both these cases deal with time, but in a different manner. The existing TimeChange event and how topomap and Brain respond to it matches use case (2). Hence, for use case (1) it's probably a good idea to have a different type of event.

wmvanvliet avatar Aug 30 '24 05:08 wmvanvliet

Sounds reasonable to me! Agreed you need separate event types

larsoner avatar Aug 30 '24 18:08 larsoner

Some code I made for mne-qt-browser using TimeChange event

from pathlib import Path
import numpy as np
import mne
from mne.viz.ui_events import TimeChange, link, publish, subscribe

mne.viz.set_browser_backend('qt')  # 'qt' or 'matplotlib'

sample_dir = mne.datasets.sample.data_path()
raw_path = Path(sample_dir) / 'MEG' / 'sample' / 'sample_audvis_raw.fif'
raw = mne.io.read_raw(raw_path)
raw2 = raw.copy()

# Plot data in two separate databrowsers
fig1 = raw.plot(block=False, duration=10, precompute=False, theme="light")
fig2 = raw2.plot(block=False, duration=10, precompute=False, theme="light")

def notify_time_range_change(plt):
    times = plt.mne.times
    publish(plt.weakmain(), TimeBrowse(time=(times[0], times[-1])))
    
# Need to hook this function into a signal that is emitted when the time changes
fig1.mne.plt.sigXRangeChanged.connect(notify_time_range_change)
fig2.mne.plt.sigXRangeChanged.connect(notify_time_range_change)

tolerance = 0.005

fig_list = [fig1,fig2]
def on_time_range_change(event):
    for f in fig_list:
        if np.abs(f.mne.times[0] - event.time[0]) < tolerance:
           continue
        f.mne.plt.setXRange(event.time[0], event.time[1], padding=0)


subscribe(fig1, "time_browse", on_time_range_change)
subscribe(fig2, "time_browse", on_time_range_change)

# Link the two databrowsers together
link(fig1, fig2)

nmarkowitz avatar Sep 03 '24 14:09 nmarkowitz

@wmvanvliet I made a draft pull request with this implementation in qt databrowser. Scrolling through time and channels is working.

https://github.com/mne-tools/mne-qt-browser/pull/286

Requires checking out mne-python branch https://github.com/mne-tools/mne-python/pull/12819

nmarkowitz avatar Sep 05 '24 22:09 nmarkowitz