topomap with layout

Hi!

I would like to plot a topomap from obtained psd_welch() values.
However I don’t know how to find the channel and position information, so I tried to do the following using a Layout:

But I couldn’t manage to fit the sensors into the blue circle. I tried changing the sphere, but it only affects to the lines drawing the head. Is there any normalization I should apply to the layout positions so they fit the blue circle properly?

Thanks!

you have an issue with the head coordinate system (defined with 3 fiducials) and your channel
locations.

did you hack the measure info? was there an issue during acquisition?

Alex

Thnaks! It’s one subject of the camcan, so I’ll have a closer look at these details

Hi @agramfort! I’ve been reviewing it but in the code I’m only using the channels positions used in ‘Vectorview-all.lout’ layout included in MNE:

layout='Vectorview-all.lout'
laypos = mne.channels.read_layout(layout).pos

So I’m only passing this to the plot_topomat function.

If a simplified version can help, just try this:

layout='Vectorview-all.lout'
laypos = mne.channels.read_layout(layout).pos

psd_welch=np.random.rand(laypos.shape[0])

mne.viz.plot_topomap(psd_welch, pos=laypos, sphere=0.5)

Which gives:
Captura de pantalla 2021-10-05 a las 17.32.46

Hi @guiomar,
I’m not an MEG guy, so I never used layouts, but here are my thoughts:
The layout you read has center away from (0, 0, 0):

laypos.mean(axis=0)
# array([0.47688583, 0.46079796, 0.03376805, 0.02814004])

so the position of the sensors that you see in the topomap is correct.
The layout seems not to be in head coordinates. When applying montages the channel positions are transformed to head coordinates. I don’t think you can apply layouts, so you could construct a montage out of this layout and then apply it to the data.
Another, simpler, way would be to center your layout coordinates around zero and then change the sphere radius to something that looks ok. For example:

import numpy as np
import mne

layout = 'Vectorview-all.lout'
laypos = mne.channels.read_layout(layout).pos
laypos[:, :2] -= laypos[:, :2].mean(axis=0, keepdims=True)

rnd_data = np.random.random(306)
mne.viz.plot_topomap(rnd_data, laypos, sphere=0.3)

which gives something like this:
image

@agramfort @larsoner
If layouts are supposed to work out of the box when their .pos is passed to mne.viz.plot_topomap then I’d consider the behavior reported by @guiomar to be a bug. WDYT?

1 Like

Thank you @mmagnuski !! That’s super useful.

I dind’t know how to get the channel positions info from the raw meg data after applying the psd_welch(), so that’s way I tried to go with the layout. How do people usually do this?
Sorry I didn’t want you to change the things, I think with this trick I can manage. Or if you show me a more efficient way to do it, I’d be happy to learn!

Thanks a lot for replying so quickly!

I think we had a related discussion at

1 Like

I always pass the info to mne.viz.plot_topomap. So if I have epochs object I then do mne.viz.plot_topomap(some_data, epochs.info). I only used this for EEG, but I think it should work for MEG as well. Let us know if the documentation or examples/tutorials should be improved to better expose this approach!

Thanks for pointing to the discussion, @richard, I’ll take a look at it.

Thanks @richard for the related discussion!

@mmagnuski I’m working with resting data which have not been epoched. And the psd_welch() function just returns an array of values, so no more info about the channels.
How should I epoch rest data, with maybe a fixed window length? do you have any example I could look at? Thanks a lot!

If you have raw object pass raw.info as channel positions.

Thanks @mmagnuski With the tip you gave me about centering the layout, the issue is solved, So I’ll close the thread :slight_smile: Thanks once more for your super fast responses!

1 Like