diff --git a/mne/preprocessing/tests/test_fine_cal.py b/mne/preprocessing/tests/test_fine_cal.py index ac62b962d9d..26a51b0f472 100644 --- a/mne/preprocessing/tests/test_fine_cal.py +++ b/mne/preprocessing/tests/test_fine_cal.py @@ -242,7 +242,7 @@ def test_fine_cal_systems(system, tmp_path): err_limit = 15 int_order = 5 corrs = (0.13, 0.0, 0.12) - sfs = [4, 5, 125, 157] + sfs = [4, 5, 125, 159] corr_tol = 0.38 else: assert system == "triux", f"Unknown system {system}" diff --git a/mne/viz/_mpl_figure.py b/mne/viz/_mpl_figure.py index f3563b454f0..1158892b98e 100644 --- a/mne/viz/_mpl_figure.py +++ b/mne/viz/_mpl_figure.py @@ -59,6 +59,7 @@ from ..utils import Bunch, _click_ch_name, check_version, logger from ._figure import BrowserBase from .utils import ( + _BLIT_KWARGS, DraggableLine, _events_off, _fake_click, @@ -1129,9 +1130,9 @@ def _create_annotation_fig(self): self._select_annotation_span, "horizontal", minspan=0.1, - useblit=True, button=1, props=dict(alpha=0.5, facecolor=col), + **_BLIT_KWARGS, ) self.mne.ax_main.selector = selector self.mne._callback_ids["motion_notify_event"] = self.canvas.mpl_connect( @@ -1170,7 +1171,7 @@ def _update_annotation_fig(self, *, draw=True): ax.set_title(title, size=None, loc="left") if len(labels): if _OLD_BUTTONS: - ax.buttons = RadioButtons(ax, labels) + ax.buttons = RadioButtons(ax, labels, **_BLIT_KWARGS) radius = 0.15 circles = ax.buttons.circles for circle, label in zip(circles, ax.buttons.labels): @@ -1195,7 +1196,9 @@ def _update_annotation_fig(self, *, draw=True): edgecolor=edgecolors, facecolor=facecolors, ) - ax.buttons = RadioButtons(ax, labels, radio_props=radio_props) + ax.buttons = RadioButtons( + ax, labels, radio_props=radio_props, **_BLIT_KWARGS + ) else: ax.buttons = None # adjust xlim to keep equal aspect & full width (keep circles round) @@ -1471,7 +1474,9 @@ def _create_selection_fig(self): labels = list(selections_dict) # make & style the radio buttons activecolor = to_rgb(self.mne.fgcolor) + (0.5,) - radio_ax.buttons = RadioButtons(radio_ax, labels, activecolor=activecolor) + radio_ax.buttons = RadioButtons( + radio_ax, labels, activecolor=activecolor, **_BLIT_KWARGS + ) fig.mne.old_selection = 0 if _OLD_BUTTONS: for circle in radio_ax.buttons.circles: diff --git a/mne/viz/tests/test_raw.py b/mne/viz/tests/test_raw.py index c7dae919fbc..350f3ba3fbb 100644 --- a/mne/viz/tests/test_raw.py +++ b/mne/viz/tests/test_raw.py @@ -318,13 +318,16 @@ def test_scale_bar(browser_backend): assert_allclose(y_lims, bar_lims, atol=1e-4) -def test_plot_raw_selection(raw, browser_backend): +def test_plot_raw_selection(raw, browser_backend, monkeypatch): """Test selection mode of plot_raw().""" ismpl = browser_backend.name == "matplotlib" with raw.info._unlock(): raw.info["lowpass"] = 10.0 # allow heavy decim during plotting browser_backend._close_all() # ensure all are closed assert browser_backend._get_n_figs() == 0 + # https://github.com/matplotlib/matplotlib/issues/30575 + monkeypatch.setattr(mne.viz.utils, "_BLIT_KWARGS", dict(useblit=False)) + monkeypatch.setattr(mne.viz._mpl_figure, "_BLIT_KWARGS", dict(useblit=False)) fig = raw.plot(group_by="selection", proj=False) assert browser_backend._get_n_figs() == 2 sel_fig = fig.mne.fig_selection @@ -493,10 +496,13 @@ def test_plot_raw_child_figures(raw, browser_backend): fig._resize_by_factor(0.5) -def test_orphaned_annot_fig(raw, browser_backend): +def test_orphaned_annot_fig(raw, browser_backend, monkeypatch): """Test that annotation window is not orphaned (GH #10454).""" if browser_backend.name != "matplotlib": return + # https://github.com/matplotlib/matplotlib/issues/30575 + monkeypatch.setattr(mne.viz.utils, "_BLIT_KWARGS", dict(useblit=False)) + monkeypatch.setattr(mne.viz._mpl_figure, "_BLIT_KWARGS", dict(useblit=False)) assert browser_backend._get_n_figs() == 0 fig = raw.plot() _spawn_child_fig(fig, "fig_annotation", browser_backend, "a") diff --git a/mne/viz/utils.py b/mne/viz/utils.py index f40520dc882..9c71714040a 100644 --- a/mne/viz/utils.py +++ b/mne/viz/utils.py @@ -60,6 +60,8 @@ from ..utils.misc import _identity_function from .ui_events import ChannelsSelect, ColormapRange, publish, subscribe +_BLIT_KWARGS = dict(useblit=True) + _channel_type_prettyprint = { "eeg": "EEG channel", "grad": "Gradiometer", @@ -1691,7 +1693,10 @@ def __init__( # Initialize the lasso selector self.lasso = LassoSelector( - ax, onselect=self.on_select, props=dict(color="red", linewidth=0.5) + ax, + onselect=self.on_select, + props=dict(color="red", linewidth=0.5), + **_BLIT_KWARGS, ) self.selection = list() self.selection_inds = np.array([], dtype="int") diff --git a/tools/install_pre_requirements.sh b/tools/install_pre_requirements.sh index 20af2997099..94a78a8b2fa 100755 --- a/tools/install_pre_requirements.sh +++ b/tools/install_pre_requirements.sh @@ -32,10 +32,9 @@ python -m pip install $STD_ARGS --only-binary ":all:" --default-timeout=60 \ "tables>=3.10.3.dev0" \ "statsmodels>=0.15.0.dev697" \ "pyarrow>=22.0.0.dev0" \ + "matplotlib>=3.11.0.dev0" \ "h5py>=3.13.0" echo "::endgroup::" -# https://github.com/matplotlib/matplotlib/issues/30575 -# "matplotlib>=3.11.0.dev0" \ # No Numba because it forces an old NumPy version echo "::group::VTK" @@ -50,10 +49,10 @@ python -m pip install $STD_ARGS \ "git+https://github.com/nilearn/nilearn" \ "git+https://github.com/pierreablin/picard" \ https://gitlab.com/obob/pymatreader/-/archive/master/pymatreader-master.zip \ - git+https://github.com/mne-tools/mne-qt-browser \ - git+https://github.com/mne-tools/mne-bids \ - git+https://github.com/nipy/nibabel \ - git+https://github.com/joblib/joblib \ + git+https://github.com/mne-tools/mne-qt-browser \ + git+https://github.com/mne-tools/mne-bids \ + git+https://github.com/nipy/nibabel \ + git+https://github.com/joblib/joblib \ git+https://github.com/h5io/h5io \ git+https://github.com/BUNPC/pysnirf2 \ git+https://github.com/the-siesta-group/edfio \