codecov[bot]: # [Codecov](https://codecov.io/gh/mne-tools/mne-python/pull/6184?src=pr&el=h1) Report
> Merging [#6184](https://codecov.io/gh/mne-tools/mne-python/pull/6184?src=pr&el=desc) into [master](https://codecov.io/gh/mne-tools/mne-python/commit/8ac51be3e8eeaeb25adaafd8d580fee4dff0f558?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.


```diff
@@            Coverage Diff             @@
##           master    #6184      +/-   ##
==========================================
+ Coverage   89.01%   89.01%   +<.01%     
==========================================
  Files         410      410              
  Lines       73883    73892       +9     
  Branches    12255    12256       +1     
==========================================
+ Hits        65765    65776      +11     
+ Misses       5223     5221       -2     
  Partials     2895     2895
```



cbrnr: LGTM!
diff --git a/doc/contributing.rst b/doc/contributing.rst
index e4f0c9e7d..15faa7e05 100644
--- a/doc/contributing.rst
+++ b/doc/contributing.rst
@@ -33,10 +33,12 @@ you can follow those steps:
 
      $ git clone git@github.com:mne-tools/mne-python.git
      $ cd mne-python
-     $ conda env create -f environment.yml
-     $ conda activate mne
-     $ pip install -e .
+     $ conda env create -f environment.yml -n mne-dev
+     $ conda activate mne-dev
+     $ pip install -e .  # or python setup.py develop
 
+Note: -n flag provides the name for the new (development) environment, and
+overrides any name specified in the .yml file.
 To check the installation, you can enter the following commands:
 
   .. code-block:: console
diff --git a/mne/annotations.py b/mne/annotations.py
index a7a97fc1c..311e56dbd 100644
--- a/mne/annotations.py
+++ b/mne/annotations.py
@@ -575,6 +575,12 @@ def read_annotations(fname, sfreq='auto', uint16_codec=None):
     -------
     annot : instance of Annotations | None
         The annotations.
+
+    Notes
+    -----
+    The annotations stored in a .csv require the onset columns to be
+    timestamps. If you have onsets as floats (in seconds), you should use the
+    .txt extension.
     """
     from .io.brainvision.brainvision import _read_annotations_brainvision
     from .io.eeglab.eeglab import _read_annotations_eeglab
@@ -648,6 +654,14 @@ def _read_annotations_csv(fname):
     description = df['description'].values
     if orig_time == 0:
         orig_time = None
+
+    if onset_dt.unique().size != onset.unique().size:
+        warn("The number of onsets in the '.csv' file (%d) does not match "
+             "the number of onsets in the Annotations created (%d). If "
+             "this happens because you did not encode your onsets as "
+             "timestamps you should save your files as '.txt'." %
+             (onset_dt.unique().size, onset.unique().size))
+
     return Annotations(onset, duration, description, orig_time)
 
 
diff --git a/mne/viz/evoked.py b/mne/viz/evoked.py
index 75719125f..3d96540ca 100644
--- a/mne/viz/evoked.py
+++ b/mne/viz/evoked.py
@@ -579,7 +579,7 @@ def _plot_image(data, ax, this_type, picks, cmap, unit, units, scalings, times,
     _check_if_nan(data)
 
     im, t_end = _plot_masked_image(
-        ax, data, times, mask, picks=None, yvals=None, cmap=cmap[0],
+        ax, data, times, mask, yvals=None, cmap=cmap[0],
         vmin=vmin, vmax=vmax, mask_style=mask_style, mask_alpha=mask_alpha,
         mask_cmap=mask_cmap)
 
@@ -1875,6 +1875,8 @@ def plot_compare_evokeds(evokeds, picks=None, gfp=False, colors=None,
     _validate_type(vlines, (list, tuple), "vlines", "list or tuple")
 
     picks = [] if picks is None else picks
+    if title is None and picks in _DATA_CH_TYPES_SPLIT:
+        title = _handle_default('titles')[picks]
     picks = _picks_to_idx(info, picks, allow_empty=True)
     if len(picks) == 0:
         logger.info("No picks, plotting the GFP ...")
diff --git a/mne/viz/topo.py b/mne/viz/topo.py
index 3ff72dde7..f2e7ce65c 100644
--- a/mne/viz/topo.py
+++ b/mne/viz/topo.py
@@ -297,7 +297,7 @@ def _imshow_tfr(ax, ch_idx, tmin, tmax, vmin, vmax, onselect, ylim=None,
     times = np.linspace(tmin, tmax, num=tfr[ch_idx].shape[1])
 
     img, t_end = _plot_masked_image(
-        ax, tfr[ch_idx], times, mask, picks=None, yvals=freq, cmap=cmap,
+        ax, tfr[ch_idx], times, mask, yvals=freq, cmap=cmap,
         vmin=vmin, vmax=vmax, mask_style=mask_style, mask_alpha=mask_alpha,
         mask_cmap=mask_cmap, yscale=yscale)
 
diff --git a/mne/viz/utils.py b/mne/viz/utils.py
index 5c04bf883..45c92c8ae 100644
--- a/mne/viz/utils.py
+++ b/mne/viz/utils.py
@@ -32,7 +32,8 @@ from ..io.pick import (channel_type, channel_indices_by_type, pick_channels,
                        pick_info, _picks_by_type, pick_channels_cov)
 from ..rank import compute_rank
 from ..io.proj import setup_proj
-from ..utils import verbose, set_config, warn, _check_ch_locs, _check_option
+from ..utils import (verbose, set_config, warn, _check_ch_locs, _check_option,
+                     logger)
 
 from ..selection import (read_selection, _SELECTIONS, _EEG_SELECTIONS,
                          _divide_to_regions)
@@ -2557,7 +2558,7 @@ def _set_title_multiple_electrodes(title, combine, ch_names, max_chans=6,
             title = "{} of {} {}".format(
                 combine, len(ch_names), ch_type)
         elif len(ch_names) > max_chans and combine != "gfp":
-            warn("More than {} channels, truncating title ...".format(
+            logger.info("More than {} channels, truncating title ...".format(
                 max_chans))
             title += ", ...\n({} of {} {})".format(
                 combine, len(ch_names), ch_type,)
@@ -2576,7 +2577,7 @@ def _check_time_unit(time_unit, times):
     return time_unit, times
 
 
-def _plot_masked_image(ax, data, times, mask=None, picks=None, yvals=None,
+def _plot_masked_image(ax, data, times, mask=None, yvals=None,
                        cmap="RdBu_r", vmin=None, vmax=None, ylim=None,
                        mask_style="both", mask_alpha=.25, mask_cmap="Greys",
                        yscale="linear"):

BUG: "mne.read_annotations"

#### Describe the bug
When I used the command '**mne.read_annotations'** to read .csv file. The **onset** always is 0.  However, the **duration** and **description** work well. If I change the file into .txt, it works correctly. 



diff --git a/mne/tests/test_annotations.py b/mne/tests/test_annotations.py
index 9e1f33852..37ec0f376 100644
--- a/mne/tests/test_annotations.py
+++ b/mne/tests/test_annotations.py
@@ -686,8 +686,22 @@ def dummy_annotation_csv_file(tmpdir_factory):
     return fname
 
 
+@pytest.fixture(scope='session')
+def dummy_broken_annotation_csv_file(tmpdir_factory):
+    """Create csv file for testing."""
+    content = ("onset,duration,description\n"
+               "1.,1.0,AA\n"
+               "3.,2.425,BB")
+
+    fname = tmpdir_factory.mktemp('data').join('annotations_broken.csv')
+    fname.write(content)
+    return fname
+
+
 @requires_version('pandas', '0.16')
-def test_io_annotation_csv(dummy_annotation_csv_file, tmpdir_factory):
+def test_io_annotation_csv(dummy_annotation_csv_file,
+                           dummy_broken_annotation_csv_file,
+                           tmpdir_factory):
     """Test CSV input/output."""
     annot = read_annotations(str(dummy_annotation_csv_file))
     assert annot.orig_time == 1038942071.7201
@@ -707,6 +721,10 @@ def test_io_annotation_csv(dummy_annotation_csv_file, tmpdir_factory):
     annot2 = read_annotations(fname)
     _assert_annotations_equal(annot, annot2)
 
+    # Test broken .csv that does not use timestamps
+    with pytest.warns(RuntimeWarning, match='The number of onsets in the'):
+        annot2 = read_annotations(str(dummy_broken_annotation_csv_file))
+
 
 # Test for IO with .txt files
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.16
apptools==5.3.0
babel==2.17.0
certifi==2025.1.31
charset-normalizer==3.4.1
contourpy==1.3.0
coverage==7.8.0
cycler==0.12.1
deepdiff==8.4.2
dipy==1.10.0
docutils==0.21.2
envisage==7.0.3
exceptiongroup==1.2.2
execnet==2.1.1
flake8==7.2.0
fonttools==4.56.0
h5py==3.13.0
idna==3.10
imagesize==1.4.1
importlib_metadata==8.6.1
importlib_resources==6.5.2
iniconfig==2.1.0
Jinja2==3.1.6
joblib==1.4.2
kiwisolver==1.4.7
lxml==5.3.1
MarkupSafe==3.0.2
matplotlib==3.9.4
mayavi==4.8.2
mccabe==0.7.0
-e git+https://github.com/mne-tools/mne-python.git@8ac51be3e8eeaeb25adaafd8d580fee4dff0f558#egg=mne
neo==0.14.0
nibabel==5.3.2
nilearn==0.11.1
numexpr==2.10.2
numpy==2.0.2
numpydoc==1.8.0
orderly-set==5.3.0
packaging==24.2
pandas==2.2.3
patsy==1.0.1
pillow==11.1.0
pluggy==1.5.0
psutil==7.0.0
pycodestyle==2.13.0
pydocstyle==6.3.0
pyface==8.0.0
pyflakes==3.3.1
Pygments==2.19.1
pyparsing==3.2.3
PyQt5==5.15.11
PyQt5-Qt5==5.15.16
PyQt5_sip==12.17.0
pysurfer @ https://api.github.com/repos/nipy/PySurfer/zipball/master#sha256=3832922dcfbe6612b1fe8c0618b82e9212d3a64964fbbad174e1c75a8c230808
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-faulthandler==2.0.1
pytest-mock==3.14.0
pytest-sugar==1.0.0
pytest-timeout==2.3.1
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
python-picard==0.8
pytz==2025.2
quantities==0.16.1
requests==2.32.3
scikit-learn==1.6.1
scipy==1.13.1
setuptools-scm==8.2.0
sip==6.10.0
six==1.17.0
snowballstemmer==2.2.0
Sphinx==7.4.7
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
statsmodels==0.14.4
tabulate==0.9.0
termcolor==2.5.0
threadpoolctl==3.6.0
tomli==2.2.1
tqdm==4.67.1
traits==7.0.2
traitsui==8.0.0
trx-python==0.3
typing_extensions==4.13.0
tzdata==2025.2
urllib3==2.3.0
vtk==9.4.2
xlrd==2.0.1
zipp==3.21.0

name: mne-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.16
      - apptools==5.3.0
      - babel==2.17.0
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - contourpy==1.3.0
      - coverage==7.8.0
      - cycler==0.12.1
      - deepdiff==8.4.2
      - dipy==1.10.0
      - docutils==0.21.2
      - envisage==7.0.3
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - flake8==7.2.0
      - fonttools==4.56.0
      - h5py==3.13.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.6.1
      - importlib-resources==6.5.2
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - joblib==1.4.2
      - kiwisolver==1.4.7
      - lxml==5.3.1
      - markupsafe==3.0.2
      - matplotlib==3.9.4
      - mayavi==4.8.2
      - mccabe==0.7.0
      - neo==0.14.0
      - nibabel==5.3.2
      - nilearn==0.11.1
      - numexpr==2.10.2
      - numpy==2.0.2
      - numpydoc==1.8.0
      - orderly-set==5.3.0
      - packaging==24.2
      - pandas==2.2.3
      - patsy==1.0.1
      - pillow==11.1.0
      - pluggy==1.5.0
      - psutil==7.0.0
      - pycodestyle==2.13.0
      - pydocstyle==6.3.0
      - pyface==8.0.0
      - pyflakes==3.3.1
      - pygments==2.19.1
      - pyparsing==3.2.3
      - pyqt5==5.15.11
      - pyqt5-qt5==5.15.16
      - pyqt5-sip==12.17.0
      - pysurfer==0.12.dev0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-faulthandler==2.0.1
      - pytest-mock==3.14.0
      - pytest-sugar==1.0.0
      - pytest-timeout==2.3.1
      - pytest-xdist==3.6.1
      - python-dateutil==2.9.0.post0
      - python-picard==0.8
      - pytz==2025.2
      - quantities==0.16.1
      - requests==2.32.3
      - scikit-learn==1.6.1
      - scipy==1.13.1
      - setuptools-scm==8.2.0
      - sip==6.10.0
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==7.4.7
      - sphinxcontrib-applehelp==2.0.0
      - sphinxcontrib-devhelp==2.0.0
      - sphinxcontrib-htmlhelp==2.1.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==2.0.0
      - sphinxcontrib-serializinghtml==2.0.0
      - statsmodels==0.14.4
      - tabulate==0.9.0
      - termcolor==2.5.0
      - threadpoolctl==3.6.0
      - tomli==2.2.1
      - tqdm==4.67.1
      - traits==7.0.2
      - traitsui==8.0.0
      - trx-python==0.3
      - typing-extensions==4.13.0
      - tzdata==2025.2
      - urllib3==2.3.0
      - vtk==9.4.2
      - xlrd==2.0.1
      - zipp==3.21.0
prefix: /opt/conda/envs/mne-python

mne/tests/test_annotations.py::test_io_annotation_csv
mne/tests/test_annotations.py::test_basics mne/tests/test_annotations.py::test_crop mne/tests/test_annotations.py::test_chunk_duration mne/tests/test_annotations.py::test_raw_reject mne/tests/test_annotations.py::test_annotation_filtering mne/tests/test_annotations.py::test_annotation_omit mne/tests/test_annotations.py::test_annotation_epoching mne/tests/test_annotations.py::test_annotations_crop mne/tests/test_annotations.py::test_events_from_annot_onset_alingment mne/tests/test_annotations.py::test_event_id_function_default mne/tests/test_annotations.py::test_event_id_function_using_custom_function mne/tests/test_annotations.py::test_io_annotation_txt mne/tests/test_annotations.py::test_read_annotation_txt_orig_time
mne/tests/test_annotations.py::test_crop_more mne/tests/test_annotations.py::test_annotation_concat mne/tests/test_annotations.py::test_handle_meas_date[invalid mne/tests/test_annotations.py::test_handle_meas_date[None] mne/tests/test_annotations.py::test_handle_meas_date[Scalar] mne/tests/test_annotations.py::test_handle_meas_date[Float] mne/tests/test_annotations.py::test_handle_meas_date[Scalar mne/tests/test_annotations.py::test_handle_meas_date[valid mne/tests/test_annotations.py::test_read_annotation_txt_header mne/tests/test_annotations.py::test_annotations_simple_iteration mne/tests/test_annotations.py::test_annotations_slices mne/tests/test_annotations.py::test_sorting
mne/viz/topo.py mne/viz/evoked.py doc/contributing.rst mne/viz/utils.py mne/annotations.py
mne/viz/topo.py mne/viz/evoked.py doc/contributing.rst mne/viz/utils.py mne/annotations.py