Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/dev/14169.other.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add an example code script using ``VertexSelect`` leveraging ``source_id`` in ``20_ui_events.py``, by `Lifeng Qiu Lin`_.
4 changes: 2 additions & 2 deletions mne/viz/_brain/_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,8 +1476,8 @@ def _on_pick(self, vtk_picker, event):
# dists = dists - dists.min()
# dists = (1. - dists / dists.max()) * self._cmap_range[1]
# grid.point_data['values'][vertices] = dists * mask
idx = idx[np.argmax(np.abs(scalars[idx]))]
vertex_id = vertices[idx]
source_id = idx[np.argmax(np.abs(scalars[idx]))]
vertex_id = vertices[source_id]
# Naive way: convert pos directly to idx; i.e., apply mri_src_t
# shape = self._data[hemi]['grid_shape']
# taking into account the cell vs point difference (spacing/2)
Expand Down
56 changes: 55 additions & 1 deletion tutorials/visualization/20_ui_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
Since the figures on our website don't have any interaction capabilities, this example
will only work properly when run in an interactive environment.
"""

# Author: Marijn van Vliet <w.m.vanvliet@gmail.com>
#
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

import matplotlib.pyplot as plt
import numpy as np

import mne
from mne.viz.ui_events import TimeChange, link, publish, subscribe
from mne.viz.ui_events import TimeChange, VertexSelect, link, publish, subscribe

# Turn on interactivity
plt.ion()
Expand Down Expand Up @@ -143,3 +145,55 @@ def on_time_change(event):

# Method calls like this also emit the appropriate UI event.
fig4.set_time(0.1)


########################################################################################
# Reacting to a vertex selection
# ==============================
# Clicking a vertex on a :class:`~mne.viz.Brain` figure publishes a
# :class:`~mne.viz.ui_events.VertexSelect` event. Alongside ``vertex_id``, which is
# specific to the brain figure itself, a more useful payload is the ``source_id``: the
# index of the nearest point in the source space, which other plots need.
#
# Here we show an example to index the lead field (gain matrix) of a forward solution.
# The lead field shows the sensor pattern a unit dipole at that location would produce.
# Plotting the topomap after clicking the vertex answers the question: if this patch of
# cortex were active, which sensors would see it?

fwd = mne.read_forward_solution(
data_path / "MEG" / "sample" / "sample_audvis-meg-eeg-oct-6-fwd.fif"
)
fwd = mne.convert_forward_solution(fwd, force_fixed=True, surf_ori=True, use_cps=True)
fwd = mne.pick_types_forward(fwd, meg="mag", eeg=False)
gain = fwd["sol"]["data"] # (n_channels, n_sources)

hemi_offset = dict(
lh=0, rh=len(stc.vertices[0])
) # right hemisphere after left (offset)

fig6 = stc.plot("sample", subjects_dir=data_path / "subjects", hemi="both")
fig7, ax = plt.subplots(figsize=(4, 4), layout="constrained")


def on_vertex_select(event):
ax.clear()
if event.source_id is None:
# Parts of the mesh outside the source space
ax.set_title(f"vertex {event.vertex_id}:\nno nearby source point")
else:
column = hemi_offset[event.hemi] + event.source_id
mne.viz.plot_topomap(gain[:, column], fwd["info"], axes=ax, show=False)
ax.set_title(f"{event.hemi} source {event.source_id}")
fig7.canvas.draw()


subscribe(fig6, "vertex_select", on_vertex_select)

# Publishing an example with the strongest source in the left hemisphere.
source_id = int(np.abs(stc.lh_data).max(axis=1).argmax())
publish(
fig6,
VertexSelect(
hemi="lh", vertex_id=int(stc.vertices[0][source_id]), source_id=source_id
),
)
Loading