Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plot topomap without any interpolation between sensors? #2210

Closed
choldgraf opened this issue Jun 16, 2015 · 24 comments
Closed

Plot topomap without any interpolation between sensors? #2210

choldgraf opened this issue Jun 16, 2015 · 24 comments

Comments

@choldgraf
Copy link
Contributor

This is another one that is probably mostly useful for ecog. I'm trying to plot sensor activations on a brain plot. There are already a few functions to create custom electrode layouts and such, though I haven't found a good way to just plot a scatterplot with one point for each electrode.

For example, I was playing around with doing ICA on a few grids to see if consistent noise could be cleaned out. I wanted to look at the weights for components across the electrodes. However, the plot_components function does a bunch of field interpolation between electrodes (which makes sense with eeg/meg, but not so much with ecog I think). E.g. I get something like this:

image

What would be great is if rather than interpolating cold/hot spaces, it would just have an option to not perform any interpolation, and just give a scatterplot with x/y positions for the electrodes, where color represents values we care about. e.g., something like this:

image

Does some functionality like this already exist, or is there any desire from anyone else for it?

@kingjr
Copy link
Member

kingjr commented Jun 16, 2015

I'm quite surprised of the low amount of correspondance between the interpolated images and the scatter plots. Is this expected? Is one of them based on a Laplacian transform / current source density and not the other?

However, the plot_components function does a bunch of field interpolation between electrodes (which makes sense with eeg/meg, but not so much with ecog I think)

Why not?

Just to throw some more ideas, I think it'd be great to have an option to add a mask that surrounds the electrode arrays using a concave hull. Typically, this would be useful when 1) ECoG strips and grids have huge gaps for which it's not really meaningful to interpolate data (or is it?) and 2) avoid these huge color effects at the electrode border.

@choldgraf
Copy link
Contributor Author

The scatterplots and interpolated images shouldn't be directly compared, because I haven't made sure that I did it correctly (it was just a quick plot). Here's the code I used to make the scatterplot:

ica_elec_weights = np.dot(ica.mixing_matrix_.T, ica.pca_components_)
f, axs = plt.subplots(5, 5, figsize=(15, 15))
for i, (ax, plot_ica) in enumerate(zip(axs.ravel(), ica_elec_weights.T)):
    plot_ica = scale(plot_ica)
    ax.scatter(x_pos, y_pos, s=100, c=plot_ica, vmin=-1, vmax=1, cmap=cm.RdBu_r)
    ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    ax.set_title('Component {0}'.format(i))

As for the interpolation stuff. I'm not too familiar with how the fields are generated from the sensor traces in eeg/meg. I assume that things would be distributed around the cortical surface in a way that would be different than how they'd spread across the scalp, but maybe it's not such a big deal?

But actually, the main reason I didn't think it made sense because of the points you bring up. Ecog grids are irregularly spaced oftentimes, and they also have a relatively large border around them, which doesn't make sense when the weights spread way outside of the grid area. I think some sort of concave hull algorithm would be pretty cool.

@choldgraf
Copy link
Contributor Author

I think I did find my bug in the scatterplot code. I was transposing the ica weight matrix when I shouldn't have done so. It would be helpful in the docstring to say what the dimensions of the mixing matrix mean (e.g., if rows are features or components)

Here with fixed code:
image

And here is the topomap plot

image

@kingjr
Copy link
Member

kingjr commented Jun 16, 2015

As for the interpolation stuff. I'm not too familiar with how the fields are generated from the sensor traces in eeg/meg. I assume that things would be distributed around the cortical surface in a way that would be different than how they'd spread across the scalp

My understanding is that the interpolation are just performed at the last computing stage and is just for vizualization purposes. It is not informed by the actual underlying physics. Plus, EEG should be similar whether it's performed epi/subdurally or at scalp, shouldn't it?

I am not so fan of the scatter plots; I think we should incline the user towards pretty graphs ;). But it's true that sometimes interpolation just doesn't make sense: typically when one only has one or a few sparsely located depth electrodes (linear arrays that target deep structures).

@choldgraf
Copy link
Contributor Author

Ha, fair enough. I do a lot of scatter plots when I'm showing model R2 and stuff like that, but that's easy enough to do with ax.scatter and ax.imshow. In this case it seems like restricting the interpolation stuff to a window that covers the ecog grid would be enough.

@larsoner
Copy link
Member

I think the interpolation code makes some assumption of smoothness that is satisfied for EEG but violated for ECoG. I wonder if we could somehow have a mode that drew it with nearest-neighbor interpolation instead. That would probably be more appropriate for ECoG.

@choldgraf
Copy link
Contributor Author

Yeah I think that it'd work best if colors just moved isotropically away from the ecog sensors until they hit the field of another sensor. And if they didn't hit anything, they'd decay away relatively quickly.

@kingjr
Copy link
Member

kingjr commented Jun 17, 2015

Yeah I think that it'd work best if colors just moved isotropically away from the ecog sensors until they hit the field of another sensor. And if they didn't hit anything, they'd decay away relatively quickly.

I've never encountered this option, so I would be a bit reluctant except if you have a reference? Note that this option requires the specification of the decay parameter.

There exists multiple ways of interpolating. You can indeed take a nearest neighbor approach, although I prefer cubic interpolations so as to avoid artificial edges.

See http://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html

@larsoner
Copy link
Member

Sure, whatever approach leads to the most intelligible data (nearest neighbor, bilinear, cubic, etc.) is fine by me, so long as we can (optionally) enforce that the values at sensor locations actually achieve their measured values. I don't think what we do now does it.

@choldgraf
Copy link
Contributor Author

OK - I don't have much experience with interpolation, I usually just plot
values as scatterplots right on the electrodes since I don't have any
underlying model for how I think things will spread across the cortex. It
sounds like you guys know more about this than I do though...

On Wed, Jun 17, 2015 at 11:15 AM, Eric Larson notifications@github.com
wrote:

Sure, whatever approach leads to the most intelligible data (nearest
neighbor, bilinear, cubic, etc.) is fine by me, so long as we can
(optionally) enforce that the values at sensor locations actually achieve
their measured values. I don't think what we do now does it.


Reply to this email directly or view it on GitHub
#2210 (comment)
.

@kingjr
Copy link
Member

kingjr commented Jun 17, 2015

Sure, whatever approach leads to the most intelligible data (nearest neighbor, bilinear, cubic, etc.) is fine by me, so long as we can (optionally) enforce that the values at sensor locations actually achieve their measured values.

Absolutely.

I don't think what we do now does it.

No? I though it was using the ax.imshow() with a bilinear interpolation by default. Is there some other tricks than here (Line 470)?

OK - I don't have much experience with interpolation, I usually just plot values as scatterplots right on the electrodes since I don't have any underlying model for how I think things will spread across the cortex. It sounds like you guys know more about this than I do though...

I think that if you plot ERPs, it's generally good practice to do a current source density transform first, because you officially cannot do an average reference (unlike EEG, ECoG does not follow a sphere), and it's generally difficult to know what you should reference to. This is why most people only look at high gamma / broadband signals that are quite localized (i.e. there s not a consistant phase across channels), and therefore bypass the issue of referencing.

@larsoner
Copy link
Member

The topomap plot above does not match the scatter plot above to my eye. But maybe it's just a colormap limits issue...?

@choldgraf
Copy link
Contributor Author

@kingjr thanks for the clarification. Up to now I've only been using broadband high-gamma, though more often than not when I make brain plots I'm not actually plotting activations, but things like model R2 etc. I'm starting to get into more low-frequency and ERP analysis so I appreciate the info

@kingjr
Copy link
Member

kingjr commented Jun 17, 2015

Sure, no problem. However, note that plotting statistical metrics (p values, AUC, R², Baysien factors etc) as opposed to the actual data (ERF, alpha phase, gamma power etc) is an independent issue. If you do a F test on ERF, plotting the F statistics is still going to be affected the type of reference, but the F test on gamma power won't (that much).

Anyway, could you confirm that the discrepency between the scatter plots and the interpolated images is due to a color limit?

@choldgraf
Copy link
Contributor Author

Sure, I'll check into the discrepancy a little bit later today.

As you say, that's the reason that I've been sticking with HG activity, as
it's relatively safer to treat each electrode as independent of the others.
I know plotting statistics and such is an independent issue, but still
useful to be able to visualize on the brain which is why I mentioned
plotting topomaps without any kind of interpolation / spread in between them

On Wed, Jun 17, 2015 at 11:45 AM, J-R King notifications@github.com wrote:

Sure, no problem. However, note that plotting statistical metrics (p
values, AUC, R², Baysien factors etc) as opposed to the actual data (ERF,
alpha phase, gamma power etc) is an independent issue. If you do a F test
on ERF, plotting the F statistics is still going to be affected the type of
reference, but the F test on gamma power won't (that much).

Anyway, could you confirm that the discrepency between the scatter plots
and the interpolated images is due to a color limit?


Reply to this email directly or view it on GitHub
#2210 (comment)
.

@choldgraf
Copy link
Contributor Author

I'm pretty sure it was a color scaling issue (more or less, anyway). I forgot that on the scatterplots I was z-scoring each component first, and then plotting. Here they are with original values and their own colormaps:

image

@choldgraf
Copy link
Contributor Author

although some of them do seem to be off still

@agramfort
Copy link
Member

agramfort commented Jun 18, 2015 via email

@kingjr
Copy link
Member

kingjr commented Jun 18, 2015

first thing we could do is set to NaN values outside of convex hull of electrodes. Then use interpolation='nearest'.

If it's not already the case, I think the best is to use a common plotting function for EEG, MEG and ECoG: ie. while passing a different layout each time. Then, you would just need to write a function that generates the ECoG mask.

@agramfort I think the convex hull is only good for a start, but doesn't fit ECoG that much (but yes, we should start with easy). It's very common to have weirdly shaped and disjoint sets of electrodes (e.g. one strip over parietal, one strip down to temporo ventral) between which you probably shouldn't interpolate:

alpha_shape_convex_hull

Just some more remarks for future reference. One could think of

  • dealing with multiple clusters #easy
  • dealing with 3D to 2D projections: it's common to have both surface and depth electrodes. #hard

If anyone hasn't dealt with these visualizations problems, I'll have to implement them in about... a year. Yes, I'm a long term planner

@larsoner
Copy link
Member

+1 for convex hull to start. The second is better, but I expect to be much harder to get right in practice. Although the link you post makes it seem pretty simple, assuming the equivalent functions are present in a Python lib, which I think they are. @kingjr do you want to try?

@kingjr
Copy link
Member

kingjr commented Jun 18, 2015

@Eric89GXL I do, but not before a while...

@larsoner
Copy link
Member

No rush from my end. @choldgraf did you want to try? You could go with the simpler convex-hull solution first, or the more complete clustering one.

@choldgraf
Copy link
Contributor Author

I can give it a shot sometime soon. What I've been doing for my common
average reference is to define a grouping of electrodes (e.g. group the
grid together, group strips together independently, etc). You might be able
to do a similar kind of thing for the convex hull, though it'd get wonky
for things like a 1-d strip.

Either way, I can put this on my radar and maybe ask a few of the scikit
image guys about it (though that may have to wait a little bit as one of
them is getting married this weekend :) )

On Thu, Jun 18, 2015 at 7:03 AM, Eric Larson notifications@github.com
wrote:

No rush from my end. @choldgraf https://github.com/choldgraf did you
want to try? You could go with the simpler convex-hull solution first, or
the more complete clustering one.


Reply to this email directly or view it on GitHub
#2210 (comment)
.

@choldgraf
Copy link
Contributor Author

I think the recent 3d scatterplotting stuff is a good enough solution for ECoG, so I propose closing this for now. Topoplots would still be nice w/ ECoG, but it's an atypical visualization for the field, and it still isn't well-understood how the activity in electrodes would spread across the cortical surface. If somebody wants to keep this open lemme know and I can reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants