Skip to content

ENH: add overlay Brain GUI - #14031

Merged
larsoner merged 7 commits into
mne-tools:mainfrom
payamsash:enh/brain-overlay-selector
Jul 12, 2026
Merged

ENH: add overlay Brain GUI#14031
larsoner merged 7 commits into
mne-tools:mainfrom
payamsash:enh/brain-overlay-selector

Conversation

@payamsash

Copy link
Copy Markdown
Member

Reference issue (if any)

following #13995 and "We also have an issue with interactivity, in that the Brain interface can have widgets that control colorbar limits for example. So we'll want to add a "data key" (maybe there is some better name?) drop-down there that allows controlling the limits for the given key / set of data, and we'll need some private var to track the currently "active" (meaning: colorbar is the one shown, and the limits / smoothing etc. changed by GUI interaction) data key."

What does this implement/fix?

Add a box next to the "Color Limits", (it should be hidden when there's only one overlay), switching it should update _active_data_key and refresh the fmin/fmid/fmax/smoothing sliders. so when add_data(remove_existing=False) is called after the viewer is already open, the box should update its items. but we'd need to add a small set_items(items) method to _AbstractWdgt and put it in both _qt.py and _notebook.py, because now the set_range calls setRange(min, max) which is numeric-only and not compatible with QComboBox.

not sure if there's a simpler way? @larsoner

Additional information

I'll probably use Claude AI for code review.

@larsoner

larsoner commented Jul 8, 2026

Copy link
Copy Markdown
Member

Feel free to ping me when to look or try!

Bonus points if you update an example to show this... maybe use multiple (dSPM, sLORETA, eLORETA?) solvers in https://mne.tools/stable/auto_tutorials/inverse/30_mne_dspm_loreta.html and overlay them with some suitable alpha and different colormaps (red/green/blue?). It could make for a cool visualization at the end of the example, and then easy to test interactively. But not obligatory if you have other ideas!

@payamsash

payamsash commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

Hi again Eric , please review #13995 first, then for this PR:

  • with the interactive python it works as expected (try attached script), but with notebook I always need to do one extra click on the brain to make changes take effect. can you help with this?
  • when we change the overlay we can control the cmap (and other stuff) for that overlay but we always have both (all) overlays on the brain surface, which I guess is what we wanted. but looking at this example (still rendering) its difficult to compare when they all overlap, so I would suggest that we could have a button like lock/unlock to control the overlays on the surface. wdyt @larsoner

[test_overlay.py](https://github.com/user-attachments/files/29881122/test_overlay.py)

@larsoner

Copy link
Copy Markdown
Member

File did not attach properly... but I would say yes in the GUI having a visibility toggle for each data layer makes sense. But in my example having a fully transparent black->50% alpha green colormap, overlaid with a fully transparent black->50% alpha blue colormap, overlaid with the same in red it seems like you should be able to see where they overlap based on the hues and colors.

For notebook... it's not used super widely so is probably buggy. I don't use it in practice so your debugging might be as good as mine 😄

@payamsash
payamsash force-pushed the enh/brain-overlay-selector branch from d3b3a15 to 44d220a Compare July 11, 2026 13:41
@payamsash

payamsash commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

ok, thanks @larsoner. so I leave the notebook issue to another fix (should I document it somewhere?), also pls check the example again and feel free to modify the params.

@larsoner larsoner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah okay yeah this image:

Image

Not super useful 😄 Feel free to adjust to something you think could be useful... maybe in some example overlay the visual response and auditory response in the same brain using just two colormaps instead? Might mirror a real-world use case a bit better

Comment thread mne/viz/_brain/_brain.py Outdated
Comment on lines +3772 to +3779
# Stage scalars directly without triggering a per-overlay
# recompose; a single mesh.update() below handles all of them
# in O(N) instead of O(N²).
overlay = mesh._overlays[data_key]
scalars = np.asarray(act_data)
if mesh.smooth_mat is not None:
scalars = mesh.smooth_mat.dot(scalars)
overlay._scalars = scalars

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of messing with private attrs, can we use public ones but with a update=True default that you can set to update=False here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Also I moved the example from 30_mne_dspm_loreta.py to 10_overview.py, because this tutorial already shows audio and visual activity in sensor space, so maybe adding the overlaid brain activity here is a good idea.

@larsoner

Copy link
Copy Markdown
Member

Just pushed a little transparent=True fix

image

Thanks @payamsash !

@larsoner
larsoner merged commit 1326afe into mne-tools:main Jul 12, 2026
9 checks passed
larsoner added a commit to larsoner/mne-python that referenced this pull request Jul 14, 2026
* upstream/main:
  Make scrollbar handlers draggable (mne-tools#14040)
  [pre-commit.ci] pre-commit autoupdate (mne-tools#14052)
  Warn when Epochs events fall outside the raw data range (mne-tools#12989) (mne-tools#14004)
  Ensure epochs being concatenated have compatible event ids (mne-tools#14051)
  Widen main content area (mne-tools#14015)
  MAINT: remove dead gain/bits/value_range fields from _read_header in … (mne-tools#14047)
  ENH: replace `_get_blocks` binary reader with mffpy Reader API (mne-tools#14043)
  MAINT: Update dependency specifiers (mne-tools#14048)
  [dependabot]: Bump the actions group with 2 updates (mne-tools#14049)
  Simplify doc building with more refleak (mne-tools#14045)
  ENH: add overlay Brain GUI (mne-tools#14031)
  ENH: support multiple simultaneous overlays in Brain.add_data (mne-tools#13995)
  Add option to show a zero line in browser (mne-tools#14018)
  FIX: pass cmap name string not tuple to interactive topomap slider kwargs (mne-tools#14039)
  Doc/add ai policy pointer (mne-tools#14037)
  Allow subclasses of FigureClass to be passed to plot_raw/plot_epochs (mne-tools#13979)
  MAINT: Replace manual PNS binary block reader in `_read_segment_file` with `mffpy` (mne-tools#14030)
larsoner added a commit to sharifhsn/mne-python that referenced this pull request Jul 14, 2026
* upstream/main: (206 commits)
  Improve type checks (mne-tools#14036)
  Make scrollbar handlers draggable (mne-tools#14040)
  [pre-commit.ci] pre-commit autoupdate (mne-tools#14052)
  Warn when Epochs events fall outside the raw data range (mne-tools#12989) (mne-tools#14004)
  Ensure epochs being concatenated have compatible event ids (mne-tools#14051)
  Widen main content area (mne-tools#14015)
  MAINT: remove dead gain/bits/value_range fields from _read_header in … (mne-tools#14047)
  ENH: replace `_get_blocks` binary reader with mffpy Reader API (mne-tools#14043)
  MAINT: Update dependency specifiers (mne-tools#14048)
  [dependabot]: Bump the actions group with 2 updates (mne-tools#14049)
  Simplify doc building with more refleak (mne-tools#14045)
  ENH: add overlay Brain GUI (mne-tools#14031)
  ENH: support multiple simultaneous overlays in Brain.add_data (mne-tools#13995)
  Add option to show a zero line in browser (mne-tools#14018)
  FIX: pass cmap name string not tuple to interactive topomap slider kwargs (mne-tools#14039)
  Doc/add ai policy pointer (mne-tools#14037)
  Allow subclasses of FigureClass to be passed to plot_raw/plot_epochs (mne-tools#13979)
  MAINT: Replace manual PNS binary block reader in `_read_segment_file` with `mffpy` (mne-tools#14030)
  Fix transition bandwidth reported in 'filter too short' error (mne-tools#11406) (mne-tools#14005)
  ENH: Show the current time as a vertical line in plot_evoked_topo (mne-tools#14032)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants