Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/dev/13460.newfeature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added the ``annotation_regex`` parameter to :func:`mne.viz.plot_raw` and :func:`mne.viz.plot_ica_sources`, allowing automatic hiding of annotations that do not match the specified regular expression. The same functionality is available via :meth:`mne.io.Raw.plot` and :meth:`mne.preprocessing.ICA.plot_sources`. Contributed by `Johannes Herforth`_.
36 changes: 19 additions & 17 deletions mne/io/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,8 @@ def plot(
color=None,
bad_color="lightgray",
event_color="cyan",
*,
annotation_regex=".*",
scalings=None,
remove_dc=True,
order=None,
Expand All @@ -1934,7 +1936,6 @@ def plot(
time_format="float",
precompute=None,
use_opengl=None,
*,
picks=None,
theme=None,
overview_mode=None,
Expand All @@ -1951,22 +1952,23 @@ def plot(
color,
bad_color,
event_color,
scalings,
remove_dc,
order,
show_options,
title,
show,
block,
highpass,
lowpass,
filtorder,
clipping,
show_first_samp,
proj,
group_by,
butterfly,
decim,
annotation_regex=annotation_regex,
scalings=scalings,
remove_dc=remove_dc,
order=order,
show_options=show_options,
title=title,
show=show,
block=block,
highpass=highpass,
lowpass=lowpass,
filtorder=filtorder,
clipping=clipping,
show_first_samp=show_first_samp,
proj=proj,
group_by=group_by,
butterfly=butterfly,
decim=decim,
noise_cov=noise_cov,
event_id=event_id,
show_scrollbars=show_scrollbars,
Expand Down
2 changes: 2 additions & 0 deletions mne/preprocessing/ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,7 @@ def plot_sources(
precompute=None,
use_opengl=None,
*,
annotation_regex=".*",
psd_args=None,
theme=None,
overview_mode=None,
Expand All @@ -2599,6 +2600,7 @@ def plot_sources(
title=title,
show=show,
block=block,
annotation_regex=annotation_regex,
psd_args=psd_args,
show_first_samp=show_first_samp,
show_scrollbars=show_scrollbars,
Expand Down
6 changes: 5 additions & 1 deletion mne/viz/_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import importlib
import inspect
import re
from abc import ABC, abstractmethod
from collections import OrderedDict
from contextlib import contextmanager
Expand Down Expand Up @@ -182,7 +183,10 @@ def _setup_annotation_colors(self):
segment_colors[key] = next(color_cycle)
self.mne.annotation_segment_colors = segment_colors
# init a couple other annotation-related variables
self.mne.visible_annotations = {label: True for label in labels}
annot_regex = re.compile(self.mne.annotation_regex)
self.mne.visible_annotations = {
label: True if annot_regex.findall(label) else False for label in labels
}
self.mne.show_hide_annotation_checkboxes = None

def _update_annotation_segments(self):
Expand Down
9 changes: 9 additions & 0 deletions mne/viz/ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def plot_ica_sources(
precompute=None,
use_opengl=None,
*,
annotation_regex=".*",
psd_args=None,
theme=None,
overview_mode=None,
Expand Down Expand Up @@ -92,6 +93,11 @@ def plot_ica_sources(
%(time_format)s
%(precompute)s
%(use_opengl)s
annotation_regex : str
A regex pattern applied to each annotation's label.
Matching labels remain visible, non-matching labels are hidden.

.. versionadded:: 1.11
psd_args : dict | None
Dictionary of arguments to pass to :meth:`~mne.Epochs.compute_psd` in
interactive mode. Ignored if ``inst`` is not supplied. If ``None``,
Expand Down Expand Up @@ -140,6 +146,7 @@ def plot_ica_sources(
show=show,
title=title,
block=block,
annotation_regex=annotation_regex,
psd_args=psd_args,
show_first_samp=show_first_samp,
show_scrollbars=show_scrollbars,
Expand Down Expand Up @@ -1292,6 +1299,7 @@ def _plot_sources(
precompute,
use_opengl,
*,
annotation_regex=".*",
psd_args,
theme=None,
overview_mode=None,
Expand Down Expand Up @@ -1415,6 +1423,7 @@ def _plot_sources(
decim=1,
# events
event_times=None if is_raw else event_times,
annotation_regex=annotation_regex,
# preprocessing
projs=list(),
projs_on=np.array([], dtype=bool),
Expand Down
9 changes: 8 additions & 1 deletion mne/viz/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def plot_raw(
color=None,
bad_color="lightgray",
event_color="cyan",
*,
annotation_regex=".*",
scalings=None,
remove_dc=True,
order=None,
Expand All @@ -61,7 +63,6 @@ def plot_raw(
precompute=None,
use_opengl=None,
picks=None,
*,
theme=None,
overview_mode=None,
splash=True,
Expand Down Expand Up @@ -99,6 +100,11 @@ def plot_raw(
Color to make bad channels.
%(event_color)s
Defaults to ``'cyan'``.
annotation_regex : str
A regex pattern applied to each annotation's label.
Matching labels remain visible, non-matching labels are hidden.

.. versionadded:: 1.11
%(scalings)s
remove_dc : bool
If True remove DC component when plotting data.
Expand Down Expand Up @@ -373,6 +379,7 @@ def plot_raw(
event_times=event_times,
event_nums=event_nums,
event_id_rev=event_id_rev,
annotation_regex=annotation_regex,
# preprocessing
projs=projs,
projs_on=projs_on,
Expand Down
16 changes: 16 additions & 0 deletions mne/viz/tests/test_ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,22 @@ def test_plot_ica_sources(raw_orig, browser_backend, monkeypatch):
leg = ax.get_legend()
assert len(leg.get_texts()) == len(ica.exclude) == 1

# Check if annotation filtering works - All annotations
annot = Annotations([0.1, 0.3], [0.1, 0.1], ["test", "test2"])
raw.set_annotations(annot)

fig = ica.plot_sources(raw)

assert fig.mne.visible_annotations["test"] and fig.mne.visible_annotations["test2"]

# Check if annotation filtering works - filtering annotations
# This should only make test2 visible and hide test
fig = ica.plot_sources(raw, annotation_regex="2$")

assert (
not fig.mne.visible_annotations["test"] and fig.mne.visible_annotations["test2"]
)

# test passing psd_args argument
ica.plot_sources(epochs, psd_args=dict(fmax=50))

Expand Down
17 changes: 17 additions & 0 deletions mne/viz/tests/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,23 @@ def test_plot_annotations(raw, browser_backend):
fig._toggle_single_channel_annotation(ch_pick, 0)
assert fig.mne.inst.annotations.ch_names[0] == (ch_pick,)

# Check if annotation filtering works - All annotations
annot = Annotations([42, 50], [1, 1], ["test", "test2"], raw.info["meas_date"])
with pytest.warns(RuntimeWarning, match="expanding outside"):
raw.set_annotations(annot)

fig = raw.plot()

assert fig.mne.visible_annotations["test"] and fig.mne.visible_annotations["test2"]

# Check if annotation filtering works - filtering annotations
# This should only make test2 visible and hide test
fig = raw.plot(annotation_regex="2$")

assert (
not fig.mne.visible_annotations["test"] and fig.mne.visible_annotations["test2"]
)


@pytest.mark.parametrize("active_annot_idx", (0, 1, 2))
def test_overlapping_annotation_deletion(raw, browser_backend, active_annot_idx):
Expand Down
Loading