Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Fix bug with scale bar overplotting #12721

Merged
merged 4 commits into from
Jul 17, 2024
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
2 changes: 2 additions & 0 deletions doc/changes/devel/12721.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix bug with overplotting of butterfly labels in :func:`mne.viz.plot_raw` and related
functions and methods, by `Eric Larson`_.
9 changes: 9 additions & 0 deletions mne/commands/mne_browse_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ def run():
default=None,
action="store_true",
)
parser.add_option(
"--butterfly",
dest="butterfly",
help="Plot in butterfly mode",
default=False,
action="store_true",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()

Expand Down Expand Up @@ -167,6 +174,7 @@ def run():
pass
filterchpi = options.filterchpi
verbose = options.verbose
butterfly = options.butterfly

if raw_in is None:
parser.print_help()
Expand Down Expand Up @@ -202,6 +210,7 @@ def run():
lowpass=lowpass,
filtorder=filtorder,
clipping=clipping,
butterfly=butterfly,
proj=not proj_off,
verbose=verbose,
show=True,
Expand Down
10 changes: 9 additions & 1 deletion mne/viz/_mpl_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1778,9 +1778,17 @@ def _check_update_vscroll_clicked(self, event):

def _show_scalebars(self):
"""Add channel scale bars."""
for offset, pick in zip(self.mne.trace_offsets, self.mne.picks):
for pi, pick in enumerate(self.mne.picks):
this_name = self.mne.ch_names[pick]
this_type = self.mne.ch_types[pick]
# TODO: Simplify this someday -- we have to duplicate the challenging
# logic of _draw_traces here
offset_ixs = (
self.mne.picks
if self.mne.butterfly and self.mne.ch_selections is None
else slice(None)
)
offset = self.mne.trace_offsets[offset_ixs][pi]
if (
this_type not in self.mne.scalebars
and this_type != "stim"
Expand Down
37 changes: 37 additions & 0 deletions mne/viz/tests/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import itertools
import os
from copy import deepcopy
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
import pytest
from matplotlib import backend_bases
from numpy.testing import assert_allclose, assert_array_equal

import mne
from mne import Annotations, create_info, pick_types
from mne._fiff.pick import _DATA_CH_TYPES_ORDER_DEFAULT, _PICK_TYPES_DATA_DICT
from mne.annotations import _sync_onset
Expand All @@ -29,6 +31,9 @@
from mne.viz import plot_raw, plot_sensors
from mne.viz.utils import _fake_click, _fake_keypress

base_dir = Path(__file__).parents[2] / "io" / "tests" / "data"
raw_fname = base_dir / "test_raw.fif"


def _get_button_xy(buttons, idx):
from mne.viz._mpl_figure import _OLD_BUTTONS
Expand Down Expand Up @@ -1214,3 +1219,35 @@ def test_plotting_memory_garbage_collection(raw, pg_backend):

assert len(mne_qt_browser._browser_instances) == 0
_assert_no_instances(MNEQtBrowser, "after closing")


def test_plotting_scalebars(browser_backend, qtbot):
"""Test that raw scalebars are not overplotted."""
ismpl = browser_backend.name == "matplotlib"
raw = mne.io.read_raw_fif(raw_fname).crop(0, 1).load_data()
fig = raw.plot(butterfly=True)
if ismpl:
ch_types = [text.get_text() for text in fig.mne.ax_main.get_yticklabels()]
assert ch_types == ["mag", "grad", "eeg", "eog", "stim"]
delta = 0.25
offset = 0
else:
qtbot.wait_exposed(fig)
for _ in range(10):
ch_types = list(fig.mne.channel_axis.ch_texts) # keys
if len(ch_types) > 0:
break
qtbot.wait(100) # pragma: no cover
# the grad/mag difference here is intentional in _pg_figure.py
assert ch_types == ["grad", "mag", "eeg", "eog", "stim"]
delta = 0.5 # TODO: Probably should also be 0.25?
offset = 1
larsoner marked this conversation as resolved.
Show resolved Hide resolved
assert ch_types.pop(-1) == "stim"
for ci, ch_type in enumerate(ch_types, offset):
err_msg = f"{ch_type=} should be centered around y={ci}"
this_bar = fig.mne.scalebars[ch_type]
if ismpl:
yvals = this_bar.get_data()[1]
else:
yvals = this_bar.get_ydata()
assert_allclose(yvals, [ci - delta, ci + delta], err_msg=err_msg)
Loading