@agramfort pointed out that in ICA overlay plots (i.e., visualization of Evoked before and after artifact removal via ICA), the displayed cleaned Evoked isn't baseline-corrected, even if the input was baseline-corrected.

I've tracked this down to an issue in mne.viz.ica.plot_ica_overlay()
The root of our problem is that evoked_cln is not baseline-corrected before it is being submitted to _plot_ica_overlay_evoked(). This in itself could be tolerated; however, since our input data (called inst here) was already baseline-corrected (by us, before invoking plot_overlay()), we end up with an overlay of a baseline-corrected and a non-baseline-corrected Evoked.
By applying baseline correction to evoked_cln before plotting, I get the expected result:
evoked_cln = ica.apply(inst.copy(), exclude=exclude)
evoked_cln.apply_baseline()
fig = _plot_ica_overlay_evoked(evoked=inst, evoked_cln=evoked_cln,
title=title, show=show)

So now I thought: neat, that'll be an easy fix! Just check if the passed Evoked instance has been baseline-corrected; and if yes, also baseline-correct the cleaned Evoked.
But there is no Evoked.baseline attribute as there is for Epochs. Therefore it seems to be impossible to find out whether an Evoked has been baseline-corrected or not.
I suggest we
.baseline attribute to mne.Evoked, which is inherited from the Epochs used for averagingmne.viz.ica.plot_ica_overlay():inst.baseline is set, apply the same baseline correction to evoked_cln,evoked_clnAlternatively we could also consider adding this check to ICA.apply(): if the passed Evoked has been baseline-corrected, apply the same baseline correction to the cleaned Evoked before returning it.
Thoughts?
cc @cbrnr
Of course one could also argue that the current behavior is, technically, absolutely correct: You pass in an Evoked, remove some ICs, and plot the result without altering it any further (e.g., through baseline correction).
Considering this, we should at least add a baseline kwarg to plot_ica_overlay(), which would apply baseline correction to the input and to the cleaned data before plotting.
(However, I personally feel it's kind of misleading comparing an Evoked after baseline correction with one that was not baseline-corrected)
I'd add a baseline attribute to be consistent with epochs.
Just to get some more opinions on the underlying issue I'm trying to solve, I'd like to hear what regular users of ICA think. Pinging @cbrnr @sappelhoff @SophieHerbst @dnacombo:
I have a baseline-corrected dataset (red traces in the image below); applying ICA to remove some components introduces an offset in some channels of the cleaned data (black traces)

Applying baseline-correction to the cleaned data seems to "fix" this:

However I've never seen anyone doing this, nor have I ever done this myself – I never had the impression it was necessary. Have you ever seen anything like this?
I usually highpass filter my data, perform ICA, and then make epochs, which I then baseline-correct :thinking:
So I don't baseline correct prior to ICA and haven't encountered this problem. But if the offsets are created through the component removal, then maybe that's to be expected and doing a second baseline correction is in fact a second baseline correction, and not a fix of the first baseline correction?
I'd add a baseline attribute to be consistent with epochs.
sounds reasonable to me :+1:
What I did here was:
Then I go back to the raw data,
ICA.apply(epoch)@sappelhoff
I usually highpass filter my data, perform ICA, and then make epochs, which I then baseline-correct 🤔
So you run ICA on the continuous data?
So you run ICA on the continuous data?
yes, downsampled to 250Hz (with appropriate anti-aliasing filter)
I later apply the ICA solution to the raw, unfiltered data and then proceed to preprocess that ICA cleaned data.
it goes a bit like this:
So you run ICA on the continuous data?
yes
Wouldn't that cause ICA also to pick up all "un-interesting" artifacts that occur between trials, e.g. when a participant blinks, swallows, moves?
Also I would like to point out that the order at least of the first few channels is preserved:
I also use a procedure similar to what @sappelhoff described - or at least I don't run ICA on baseline-corrected epoched data. Technically, I use non-baseline-corrected epochs (which contain the activity of interest), but I don't use MNE epochs but basically cut my own epochs based on the raw continuous data.
@hoechenberger it's true that doing baseline correction if you already high
pass filtered the data
is unnecessary. Can you remove this extra baseline correction to see how it
behaves?
>
Wouldn't that cause ICA also to pick up all "un-interesting" artifacts that occur between trials, e.g. when a participant blinks, swallows, moves?
to some extend yes, ... I do cut out block breaks and then I simply trust that blinks, horizontals, and cardiac ICs are clear enough that I can reject them and I don't care about all other ICs and what they do or don't capture --> I use ICA exclusively for preprocessing/cleaning)
@hoechenberger
I've done ICA mostly with EEG data.
From raw EEG data, I usually
And they're all aligned. I don't recall having had this issue before.
Perhaps something to do with the re-referencing, which is not applied to MEG? on EEG signals, not rereferencing has a strange effect. You get a (usually first) component that sort of captures the average ref.
I cannot reproduce this issue anymore. Which is good, I suppose 😅👍
Most helpful comment
I'd add a
baselineattribute to be consistent with epochs.