Failing to generate mask and saving multiple channels data to a single image

  • MNE-Python version: 0.23.4
  • operating system: macOS 11.5.2 (20G95)

I have 2 questions about the ERDS example Compute and visualize ERDS maps — MNE 0.23.4 documentation

  1. How can I generate a single image from all selected channels? For my use case it’s fine to simply stack each channel image vertically.
  2. In my test case using B0101T.gdf from BCI Competition IV when trying to generate the mask for events of type "769", I get an empty c2 and p2 from pcluster_test causing operands could not be broadcast together with shapes (1,34,376) (0,). How can I generate the mask for cases like this, that one of the tails, or even both, from 1 or more channels, has no significance? If I do this, how the significance should be affected, considering that now we’re presenting in the same image multiple channels?

Thanks in advance!

Hi @henrique,

  1. How can I generate a single image from all selected channels? For my use case it’s fine to simply stack each channel image vertically.

I’m not sure I understand what you want to achieve here and which image/figure you are referring to. Do you want to average across the channels or do you want to combine the 3 plots in a single axes object that you plot into with .imshow() by somehow vertically stacking them? If the latter is the case (but would that really be practical?), you will most likely have to come up with your own plotting solution and probably cannot use the MNE TFR plotting functionalities.
But as I said, maybe I do not understand your use case. Maybe you could clarify if with “image” you are referring to a figure or a plot (aka, axes object).

I get an empty c2 and p2 from pcluster_test causing operands could not be broadcast together with shapes (1,34,376) (0,) . How can I generate the mask for cases like this, that one of the tails, or even both, from 1 or more channels, has no significance?

I’d do that by checking whether c1 or c2 are of zero length and if so, replace the affected one by an array of the correct size full of False values. One solution could be:

if len(c1) == 0:
    c1 = np.zeros_like(tfr_ev.data[:, ch, ...], dtype=bool)
if len(c2) == 0:
    c2 = np.zeros_like(tfr_ev.data[:, ch, ...], dtype=bool)

There are probably more elegant solutions, but this shouldn’t produce problems then for the rest of the code, I think.

1 Like

Hey @eioe thanks for your reply!

So, about 1, I’m trying to combine the 3 “image data” into 1 by “extending” the vertical axes.
Example:
Assuming we have data shaped as (n_channels, n_frequencies, n_timestamps) what I want to produce is (n_channels * n_frequencies, n_timestamps).

The use case here is to train a neural net with an image representing an event type or run. The data can be averaged out in the case of event types, but it doesn’t matter much other than the number of images we’d have is lower if we average things out. By the way, these images need to be saved to a file, so it has nothing to do with plotting/showing the plot to the end user.

More on this other thread.

About 2, I’ll test that tonight.

is there a reason not to use np.vstack(data) ?

@drammock I already have logic in place to reshape the data, but I wanted to use the same plot() method as the example. Can I use the existing tfr_ev.average().plot() to plot np.vstack(data)? I guess not because data is internal and especially because average() will perform some more data manipulation?

ah OK, now I understand what you want to do. If you want to rely on the MNE-Python plotting function, you’ll need it to be an AverageTFR object and thus you’ll have to do some hacking. You could start by splitting the tfr_ev.average().plot(...) line into separate lines with an intermediate variable (call it tfr_ev_avg) and then try to shoe-horn the data from that (suitably reshaped with numpy functions) into the shape that you want using AverageTFR.__init__() perhaps. You’ll need to adjust the freqs as well to be the appropriate length; naively it will end up as something like freqs=[5, 10, 15, 5, 10, 15, 5, 10, 15, 5, 10, 15] (assuming 3 freq bins and 4 channels) but I don’t know if it will work to have freqs that are duplicated and not monotonic though.

If that doesn’t work or sounds unappealing, then probably your best bet is working with the numpy arrays, and reading the source code of the plotting function so you can re-implement whatever aspects of it you really need.

1 Like