Repository: mne-tools/mne-python

Issue:
Annotation displayed on ICA sources when meas_date is None and first_samp is not 0 are wrong
### Description of the problem

One more time-management related issue with annotations. MWE:

```
from datetime import datetime, timezone

import numpy as np
from mne import Annotations, create_info
from mne.io import RawArray
from mne.preprocessing import ICA


#%%
# date = datetime(1995, 3, 28, 0, 0, 0, 0, tzinfo=timezone.utc)

info = create_info(5, 1000, "eeg")
data = np.random.randn(5, 10000)
raw = RawArray(data, info)
assert raw.first_samp == 0
# raw.set_meas_date(date)
annotation = Annotations(onset=4, duration=1, description="bad_test")
raw.set_annotations(annotation)
# raw.plot(theme="light", scalings="auto")

#%%
raw.crop(2, 8)
# raw.plot(theme="light", scalings="auto")

#%%
ica = ICA(
    method="picard", fit_params=dict(ortho=False, extended=True), random_state=888
)
ica.fit(raw, picks="eeg", reject_by_annotation=True)
ica.plot_sources(raw, theme="light")
```

If there is no measurement date and if `raw.first_samp` is different from `0` (e.g. by cropping), the annotations displayed in `ica.plot_sources` are not correctly set. Issue is here: https://github.com/mne-tools/mne-python/blob/7def8369d7ca691d807fe916663168c2ee4c10e0/mne/viz/ica.py#L1304-L1305

Still thinking about what is a good fix.. time-management is a real headache :exploding_head: 


Discussion:

Resolving patch:
diff --git a/mne/viz/ica.py b/mne/viz/ica.py
--- a/mne/viz/ica.py
+++ b/mne/viz/ica.py
@@ -1302,7 +1302,7 @@ def _plot_sources(
     info["bads"] = [ch_names[x] for x in exclude if x in picks]
     if is_raw:
         inst_array = RawArray(data, info, inst.first_samp)
-        inst_array.set_annotations(inst.annotations)
+        inst_array._annotations = inst.annotations
     else:
         data = data.reshape(-1, len(inst), len(inst.times)).swapaxes(0, 1)
         inst_array = EpochsArray(data, info)


Test patch:
diff --git a/mne/viz/tests/test_ica.py b/mne/viz/tests/test_ica.py
--- a/mne/viz/tests/test_ica.py
+++ b/mne/viz/tests/test_ica.py
@@ -9,7 +9,7 @@
 import matplotlib.pyplot as plt
 import numpy as np
 import pytest
-from numpy.testing import assert_equal, assert_array_equal
+from numpy.testing import assert_equal, assert_array_equal, assert_allclose
 
 from mne import (
     read_events,
@@ -319,7 +319,7 @@ def test_plot_ica_sources(raw_orig, browser_backend, monkeypatch):
     assert browser_backend._get_n_figs() == 0
     del long_raw
 
-    # test with annotations
+    # test with annotations and a measurement date
     orig_annot = raw.annotations
     raw.set_annotations(Annotations([0.2], [0.1], "Test"))
     fig = ica.plot_sources(raw)
@@ -328,6 +328,22 @@ def test_plot_ica_sources(raw_orig, browser_backend, monkeypatch):
         assert len(fig.mne.ax_hscroll.collections) == 1
     else:
         assert len(fig.mne.regions) == 1
+        assert_allclose(fig.mne.regions[0].getRegion(), (0.2, 0.3))
+
+    # test with annotations and no measurement date
+    orig_meas_date = raw.info["meas_date"]
+    raw.set_meas_date(None)
+    assert raw.first_samp != 0
+    raw.set_annotations(Annotations([0.2], [0.1], "Test"))
+    fig = ica.plot_sources(raw)
+    if browser_backend.name == "matplotlib":
+        assert len(fig.mne.ax_main.collections) == 1
+        assert len(fig.mne.ax_hscroll.collections) == 1
+    else:
+        assert len(fig.mne.regions) == 1
+        assert_allclose(fig.mne.regions[0].getRegion(), (0.2, 0.3))
+
+    raw.set_meas_date(orig_meas_date)
     raw.set_annotations(orig_annot)
 
     # test error handling