How can I animate the PSDs of multiple consecutive windows of EEG data over a topomap?

I’m currently working with a very long multi-channel EEG signal (with known channel names from the standard 10-20 system). The way I process it is to extract multiple consecutive windows from it, each window is stored as a RawArray object. I then compute the PSDs of each window using the RawArray.compute_psd() function, where I set return_freqs to True. Therefore, I can get a list of (psd, freqs) tuples, each corresponding to the one window. I also know the starting timestamps of these windows, stored in a list timestamps.

What I would like to achieve is to obtain an animated topomap over the PSDs of these windows for a given frequency band band. Specifically, for each timestamp in timestamps, I would like to get a frame of topomap showing the PSD of its corresponding window (in dB unitS). I would like this animation to be interactive, like what can be achieved in evoked.animate_topomap. The difference from evoked.animate_topomap is that I do not want to animate the original data, but the PSDs. How can I achieve this?

There’s no out-of-the-box solution for this in MNE-Python. I think in theory you could to this:

  • create an empty array, with shape (n_sensors, n_windows)
  • for each PSD you computed:
    • extract the power from band using its .get_data() method.
      • If band is a range rather than a single frequency bin, average across bins
    • stick the result (one value per sensor) into a column of your empty array
  • convert your array to an evoked object using mne.EvokedArray()
  • use its .animate_topomap() method to make the plot.

regarding getting the values in dB: do that at the step where you’re converting from a RawArray into a Spectrum.

1 Like

You could also use directly matplotlib:

  • Make sure you are running an interactive backend and enable interactive mode with plt.ion().
  • Create the figure which will host the topomap and any button you might need on the figure.
  • Loop over your (timestamps / topomaps), clear the topomap axes and plot a new one. At the end of each loop, wait for the correct amount of time depending on your timestamps.
  • Add buttons to pause/resume the loop.

Here is an example which is used with LSL (communication protocol between amplifiers/computer, thus timestamps are handled automatically): demo-realtime/topomap.py at main · fcbg-hnp-meeg/demo-realtime · GitHub
It would need some adaptation and doesn’t have any pause/resume button, but it could help to get you started.

Mathieu

1 Like