Skip to content

Adding interactive plotting of magnetic field lines to Brain#11676

Closed
wmvanvliet wants to merge 6 commits intomne-tools:mainfrom
wmvanvliet:fieldlines
Closed

Adding interactive plotting of magnetic field lines to Brain#11676
wmvanvliet wants to merge 6 commits intomne-tools:mainfrom
wmvanvliet:fieldlines

Conversation

@wmvanvliet
Copy link
Copy Markdown
Contributor

@wmvanvliet wmvanvliet commented May 4, 2023

Picking up from #8382 from way back, I've been working on a supercharged version of mne.viz.plot_evoked_field that uses our interactive Brain plotting object. Check it out:

movie1

The API for this is a new add_field() method for the Brain object:

field_map = mne.make_field_map(
    evoked,
    trans=trans,
    subject='sample',
    subjects_dir=f'{data_path}/subjects',
)

# Plot the source estimate
brain = stc.plot(
    'sample',
    subjects_dir=f'{data_path}/subjects',
    initial_time=0.08,
    hemi='both',
    surface='white',
)

# Add the field lines!
brain.add_field(evoked, field_map)

The above plot is a bit busy though. I find things are easier to interpret when we skip the EEG field patterns and we also don't plot the field density "blobs", just the contour lines:

movie2

The above is achieved by passing ch_type='meg' to mne.make_field_map and show_density=False to Brain.add_field, and background=white to stc.plot.

Screenshot of the GUI, notice the "Field strength" section in the dock:

screenshot

Example: Fixes #8382

Todo:

  • Implement Brain.add_field
  • Implement GUI elements
  • [ ] Find a way to plot just the field lines without an MRI
  • [ ] Make hemi='split' work
  • [ ] Refactor old mne.viz.plot_evoked_field function
  • Unit tests
  • Example
  • API docs
  • What's new entry

@larsoner
Copy link
Copy Markdown
Member

larsoner commented May 4, 2023

Looks nice! This is definitely something that I've missed from mne_analyze :)

A few high level thoughts/ideas offhand:

  1. Do we have to be careful / think about the interaction with brain.plot_sensors (which can plot a helmet)?
  2. I wonder if a more future compatible API might be brain.add_evoked(evoked) and brain.add_field_map(map). Just trying to think a little bit more generally, someday we might want to have for example brain.add_inverse(...), brain.add_evoked(...), brain.add_field_map(...) and the object can automatically "do everything it can": apply the inverse to the evoked and plots the STC and the field map. But I guess this could also be done via brain.add_inverse(inverse, evoked), too, so maybe overkill to go this direction.
  3. Or even better -- rather than make Brain more and more complex by adding bits of code from other places, I've been hoping that at some point we could implement a proper plotting event/publisher-subscriber system (see https://github.com/mne-tools/mne-python/wiki/GSoC-Ideas#2-event-system-for-brain-and-evoked-plots). If we did, it seems like the functionality in this PR could be achieved by something like the following I think:
    brain = stc.plot(...)
    fig = mne.viz.plot_evoked_field(..., fig=brain.figure)
    brain.connect('on_time_change', fig.set_time)
    
    and you could get the benefit of also connecting a mne.viz.plot_evoked_joint(...) or plot_evoked_topo if you wanted those to update, etc.

Even if (3) seems like a better way of accomplishing this (and it might not!) then it doesn't necessarily have to stand in the way of this PR. But if you were motivated to work on getting the event system started... :)

@wmvanvliet
Copy link
Copy Markdown
Contributor Author

(3) sounds like the way to go if we want to add even more capabilities to Brain. The file is too large and complicated as it is already. This event system sounds like a good way to achieve some of the todo items in this PR. Notably, it would be nice if the field patterns can still be plotted with our time viewer, but without a FreeSurfer brain mesh in the center (like xfit can). This is clearly out of scope of the Brain object.

@larsoner
Copy link
Copy Markdown
Member

larsoner commented May 4, 2023

it would be nice if the field patterns can still be plotted with our time viewer, but without a FreeSurfer brain mesh in the center (like xfit can).

Agreed. I think an event system could make it much easier to provide xfit-like interactive dipole fitting for example...

Should we start building an event system to allow this sort of stuff (maybe over the next month or so?), then see if we can get the equivalent functionality of this PR, or would you rather get some version of this PR in as is? I don't want to make perfect the enemy of good here, what you have is already cool and usable!

@wmvanvliet
Copy link
Copy Markdown
Contributor Author

See #11678

@wmvanvliet
Copy link
Copy Markdown
Contributor Author

Closing for now. I'll re-implement this when the ui-event system is operational.

@wmvanvliet wmvanvliet closed this Jun 12, 2023
@wmvanvliet wmvanvliet mentioned this pull request Aug 11, 2023
19 tasks
@wmvanvliet wmvanvliet deleted the fieldlines branch September 4, 2023 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

interactive sensor-level field patterns browser

2 participants