I would like to plot ERP waveform, but I am having trouble understanding how to adjust the values on the vertical axis.
I have a data file named dataAllMember that contains all the data of all the subjects, and I am trying to generate the overall waveform with the code below.
The EEG values in the raw data are in μV, but the actual output (attached image) shows 1e6 in the upper left corner.
I am guessing that the default setting is to read the value as a numerical value with a unit of V and convert it to μV for processing.
The code is based on MNE Python’s tutorial on ERP calculation.
How can I solve this problem?
The docstring of EpochsArray says for the data parameter “see notes for proper units of measure.” The notes then tell you that you should use unit V for EEG data. It sounds like you are passing it data in μV instead. Don’t do that.
FYI, in MNE-Python everything is stored in SI units. Sometimes our plotting functions will convert the units before plotting, just so that the axis labels don’t range from say 0.000001 to 0.000006 V, but instead from 1 to 6 μV. Again this is only on the plot, the underlying data object still stores the numbers in SI units. This is documented here: Algorithms and other implementation details — MNE 1.2.2 documentation
But you don’t seem to clearly state how to solve this problem, which is confusing.
The fact is: if you do not make any changes, many plot functions will not automatically convert ‘V’ to ‘µV’, so ‘1e6’ on the ordinate axis still exists. So this has to be solved manually.
# the unit is 'V' if you has change nothing so '1e6' is on the ordinate
evoked.plot()
# '1e6' is not on the ordinate but the unit is NA
evoked.plot(unit=False)
# Well! the unit is 'µV' and '1e6' is not on the ordinate
evoked.plot(scalings=dict(eeg=1))
How to solve this problem is to not load data that are stored in µV into a class that expects data in V. The original post by @OnoreCoffee said:
There are only 2 ways this can happen: a bug in one of our raw data readers, or a user loading custom data into the RawArray class. The docstring of the RawArray class says:
Proper units of measure:
V: eeg, eog, seeg, dbs, emg, ecg, bio, ecog
T: mag
T/m: grad
M: hbo, hbr
Am: dipole
AU: misc
So the way to solve the problem is to multiply your data (in µV) by 1e-6 before loading it into the RawArray class (or in your case @lee the EvokedArray class — the expected units are the same as for RawArray).
If that doesn’t solve your problem @lee then can you please:
provide a reproducible example (including loading / simulating the data)
describe clearly what you see on the plot, and how it is different from what you expect/want to see
Is it 1e6 or 1e-6? I tried multiplying by 1e-6, it worked. However, I don’t want to do that because of the loss of precision if it’s multiplying by 1e-6. Ok, but I might have to do this, if my code above doesn’t work:
evoked.plot(scalings=dict(eeg=1))
I’m new to mne, I don’t know if setting the scalings parameter can also solve this problem? Now my results look normal because the image units are µV and the ordinate doesn’t have 1e6, but I doubt there is a potential problem with doing this.
you’re correct, I mistyped before. I’ll correct the mistake in the prior post to avoid future readers’ confusion.
Your data are almost certainly stored as NumPy float64 values. These have a precision of ~1e-15. So if your data start out in µV and you convert to V, you still have a precision of ~1e-9 V. In other words the loss of precision is happening at nanoVolt levels (which should be well below the noise floor of typical EEG data).
If you really don’t want to scale the data, then you can indeed pass a scalings dict to the plotting function. If all you need is the one plot that’s probably fine… but the assumption that EEG data are stored in V (and that generally all data in MNE data classes are in SI units) is baked into MNE in a lot of places. Personally I think it’s easier / safer to scale the data once and then not have to worry about passing scalings every time I want to make a plot.