From bb552e29f92edacd8aa73afb68f48de5d3c4df24 Mon Sep 17 00:00:00 2001 From: Clemens Brunner Date: Fri, 24 Jul 2026 12:21:22 +0200 Subject: [PATCH 1/5] Make blocking consistent --- mne/_fiff/meas_info.py | 15 +++++++++++---- mne/time_frequency/spectrum.py | 23 ++++++++++++++++++----- mne/time_frequency/tests/test_spectrum.py | 2 ++ mne/utils/docs.py | 8 +++++++- mne/viz/raw.py | 6 +++--- mne/viz/topomap.py | 2 +- mne/viz/utils.py | 14 ++++++++++---- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/mne/_fiff/meas_info.py b/mne/_fiff/meas_info.py index 2e1e2a1c55c..bf0a8882759 100644 --- a/mne/_fiff/meas_info.py +++ b/mne/_fiff/meas_info.py @@ -690,7 +690,7 @@ def plot_sensors( ch_groups=None, to_sphere=True, axes=None, - block=False, + block=None, show=True, sphere=None, *, @@ -736,11 +736,18 @@ def plot_sensors( instance of Axes3D. If None (default), a new axes will be created. .. versionadded:: 0.13.0 - block : bool - Whether to halt program execution until the figure is closed. - Defaults to False. + block : bool | None + Whether to halt program execution until the figure is closed. By default + (``None``) this follows :func:`matplotlib.pyplot.show`: it blocks unless + Matplotlib's interactive mode is on (see :func:`matplotlib.pyplot.ion`), in + which case it returns immediately. Set to ``True`` to force blocking, which + is useful with ``kind="select"`` to collect the interactive selection + synchronously when interactive mode is on. .. versionadded:: 0.13.0 + .. versionchanged:: 1.13 + The default changed from ``False`` to ``None`` (follow + Matplotlib). show : bool Show figure if True. Defaults to True. %(sphere_topomap_auto)s diff --git a/mne/time_frequency/spectrum.py b/mne/time_frequency/spectrum.py index dab12d02ee1..ca79bdaeb53 100644 --- a/mne/time_frequency/spectrum.py +++ b/mne/time_frequency/spectrum.py @@ -161,7 +161,7 @@ def plot_psd_topo( fig_facecolor="k", axis_facecolor="k", axes=None, - block=False, + block=None, show=True, n_jobs=None, verbose=None, @@ -181,7 +181,9 @@ def plot_psd_topo( %(fig_facecolor)s %(axis_facecolor)s %(axes_spectrum_plot_topo)s - %(block)s + block : bool + This parameter is deprecated and will be removed in MNE 1.15; blocking now + follows Matplotlib's behavior (see ``show``). %(show)s %(n_jobs)s %(verbose)s @@ -726,7 +728,7 @@ def plot_topo( fig_facecolor="k", axis_facecolor="k", axes=None, - block=False, + block=None, show=True, ): """Plot power spectral density, separately for each channel. @@ -739,7 +741,9 @@ def plot_topo( %(fig_facecolor)s %(axis_facecolor)s %(axes_spectrum_plot_topo)s - %(block)s + block : bool + This parameter is deprecated and will be removed in MNE 1.15; blocking now + follows Matplotlib's behavior (see ``show``). %(show)s Returns @@ -777,7 +781,16 @@ def plot_topo( y_label=y_label, axes=axes, ) - plt_show(show, block=block) + if block is None: + plt_show(show) + else: + warn( + "The 'block' parameter is deprecated and will be removed in MNE 1.15; " + "blocking now follows Matplotlib's behavior. Pass show=False and call " + "matplotlib.pyplot.show() to control it.", + FutureWarning, + ) + plt_show(show, block=block) return fig @fill_doc diff --git a/mne/time_frequency/tests/test_spectrum.py b/mne/time_frequency/tests/test_spectrum.py index b27d21e43ad..2c114251b4a 100644 --- a/mne/time_frequency/tests/test_spectrum.py +++ b/mne/time_frequency/tests/test_spectrum.py @@ -718,6 +718,8 @@ def test_plot_spectrum(method, output, average, request): n_bad = sum(same_color(line.get_color(), bad_color) for line in lines) assert n_bad == 1 spectrum.plot_topo() + with pytest.warns(FutureWarning, match="'block' parameter is deprecated"): + spectrum.plot_topo(block=True) spectrum.plot_topomap() diff --git a/mne/utils/docs.py b/mne/utils/docs.py index 4723ad20019..0a756450c87 100644 --- a/mne/utils/docs.py +++ b/mne/utils/docs.py @@ -4265,7 +4265,13 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75): docdict["show"] = """\ show : bool - Show the figure if ``True``. + Show the figure if ``True``. When shown, blocking follows + :func:`matplotlib.pyplot.show`: the call blocks until the window is closed unless + Matplotlib's interactive mode is on (enabled with :func:`matplotlib.pyplot.ion`, + which IPython's Matplotlib integration turns on automatically), in which case it + returns immediately. Interactive mode is off by default, so a plain script or REPL + blocks. Pass ``show=False`` to build several figures and display them together with + a single :func:`matplotlib.pyplot.show` call. """ docdict["show_names_topomap"] = """ diff --git a/mne/viz/raw.py b/mne/viz/raw.py index 1897a3f9a6c..8a8f4824a46 100644 --- a/mne/viz/raw.py +++ b/mne/viz/raw.py @@ -554,7 +554,7 @@ def plot_raw_psd_topo( fig_facecolor="k", axis_facecolor="k", axes=None, - block=False, + block=None, show=True, n_jobs=None, verbose=None, @@ -588,8 +588,8 @@ def plot_raw_psd_topo( Defaults to black. %(axes_spectrum_plot_topo)s block : bool - Whether to halt program execution until the figure is closed. - May not work on all systems / platforms. Defaults to False. + This parameter is deprecated and will be removed in MNE 1.15; blocking now + follows Matplotlib's behavior (see ``show``). %(show)s %(n_jobs)s %(verbose)s diff --git a/mne/viz/topomap.py b/mne/viz/topomap.py index 964faf8224e..a632f48798e 100644 --- a/mne/viz/topomap.py +++ b/mne/viz/topomap.py @@ -2420,7 +2420,7 @@ def plot_evoked_topomap( interactive_colorbar=True, single_time_point=False, ) - plt_show(show, block=False) + plt_show(show) if axes is not None: fig.canvas.draw() return fig diff --git a/mne/viz/utils.py b/mne/viz/utils.py index 91659b1aa8f..1fb282688dd 100644 --- a/mne/viz/utils.py +++ b/mne/viz/utils.py @@ -941,7 +941,7 @@ def plot_sensors( ch_groups=None, to_sphere=True, axes=None, - block=False, + block=None, show=True, sphere=None, pointsize=None, @@ -992,11 +992,17 @@ def plot_sensors( %(axes_montage)s .. versionadded:: 0.13.0 - block : bool - Whether to halt program execution until the figure is closed. Defaults - to False. + block : bool | None + Whether to halt program execution until the figure is closed. By default + (``None``) this follows :func:`matplotlib.pyplot.show`: it blocks unless + Matplotlib's interactive mode is on (see :func:`matplotlib.pyplot.ion`), in + which case it returns immediately. Set to ``True`` to force blocking, which is + useful with ``kind="select"`` to collect the interactive selection synchronously + when interactive mode is on. .. versionadded:: 0.13.0 + .. versionchanged:: 1.13 + The default changed from ``False`` to ``None`` (follow Matplotlib). show : bool Show figure if True. Defaults to True. %(sphere_topomap_auto)s From 77736a24db950cbacfc11150d5fb16435dc11e8b Mon Sep 17 00:00:00 2001 From: Clemens Brunner Date: Fri, 24 Jul 2026 12:26:57 +0200 Subject: [PATCH 2/5] Add changelog entries --- doc/changes/dev/14098.apichange.rst | 1 + doc/changes/dev/14098.bugfix.rst | 1 + 2 files changed, 2 insertions(+) create mode 100644 doc/changes/dev/14098.apichange.rst create mode 100644 doc/changes/dev/14098.bugfix.rst diff --git a/doc/changes/dev/14098.apichange.rst b/doc/changes/dev/14098.apichange.rst new file mode 100644 index 00000000000..6596ae91f45 --- /dev/null +++ b/doc/changes/dev/14098.apichange.rst @@ -0,0 +1 @@ +The ``block`` parameter of :meth:`mne.time_frequency.Spectrum.plot_topo`, the legacy ``plot_psd_topo`` methods (e.g. :meth:`mne.io.Raw.plot_psd_topo`), and :func:`mne.viz.plot_raw_psd_topo` is deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib's blocking behavior, by `Clemens Brunner`_. diff --git a/doc/changes/dev/14098.bugfix.rst b/doc/changes/dev/14098.bugfix.rst new file mode 100644 index 00000000000..23ff6e66734 --- /dev/null +++ b/doc/changes/dev/14098.bugfix.rst @@ -0,0 +1 @@ +Fixed :func:`~mne.viz.plot_evoked_topomap` and :func:`~mne.viz.plot_sensors` (and the ``plot_sensors`` methods) to follow Matplotlib's blocking behavior when ``show=True`` instead of returning immediately; ``plot_sensors`` keeps its ``block`` argument (default now ``None``), by `Clemens Brunner`_. From 37aec682d385b44bcc5f9f8e9b9f826ac0074c66 Mon Sep 17 00:00:00 2001 From: Clemens Brunner Date: Fri, 24 Jul 2026 21:24:48 +0200 Subject: [PATCH 3/5] Apply review comments --- doc/changes/dev/14098.apichange.rst | 2 +- mne/time_frequency/spectrum.py | 2 +- mne/utils/docs.py | 10 +++++----- mne/viz/raw.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/changes/dev/14098.apichange.rst b/doc/changes/dev/14098.apichange.rst index 6596ae91f45..5ee68306a23 100644 --- a/doc/changes/dev/14098.apichange.rst +++ b/doc/changes/dev/14098.apichange.rst @@ -1 +1 @@ -The ``block`` parameter of :meth:`mne.time_frequency.Spectrum.plot_topo`, the legacy ``plot_psd_topo`` methods (e.g. :meth:`mne.io.Raw.plot_psd_topo`), and :func:`mne.viz.plot_raw_psd_topo` is deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib's blocking behavior, by `Clemens Brunner`_. +The ``block`` parameter of :meth:`mne.time_frequency.Spectrum.plot_topo`, the legacy ``plot_psd_topo`` methods, and :func:`mne.viz.plot_raw_psd_topo` is deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib's blocking behavior, by `Clemens Brunner`_. diff --git a/mne/time_frequency/spectrum.py b/mne/time_frequency/spectrum.py index ca79bdaeb53..0a485fc2970 100644 --- a/mne/time_frequency/spectrum.py +++ b/mne/time_frequency/spectrum.py @@ -741,7 +741,7 @@ def plot_topo( %(fig_facecolor)s %(axis_facecolor)s %(axes_spectrum_plot_topo)s - block : bool + block : bool | None This parameter is deprecated and will be removed in MNE 1.15; blocking now follows Matplotlib's behavior (see ``show``). %(show)s diff --git a/mne/utils/docs.py b/mne/utils/docs.py index 0a756450c87..e6903a8f53b 100644 --- a/mne/utils/docs.py +++ b/mne/utils/docs.py @@ -4267,11 +4267,11 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75): show : bool Show the figure if ``True``. When shown, blocking follows :func:`matplotlib.pyplot.show`: the call blocks until the window is closed unless - Matplotlib's interactive mode is on (enabled with :func:`matplotlib.pyplot.ion`, - which IPython's Matplotlib integration turns on automatically), in which case it - returns immediately. Interactive mode is off by default, so a plain script or REPL - blocks. Pass ``show=False`` to build several figures and display them together with - a single :func:`matplotlib.pyplot.show` call. + Matplotlib's interactive mode is on (enabled with :func:`matplotlib.pyplot.ion` or + IPython's ``%matplotlib`` magic command), in which case it returns immediately. + Interactive mode is off by default, so a plain script or REPL blocks. Pass + ``show=False`` to build several figures and display them together with a single + :func:`matplotlib.pyplot.show` call. """ docdict["show_names_topomap"] = """ diff --git a/mne/viz/raw.py b/mne/viz/raw.py index 8a8f4824a46..b577ee85d6f 100644 --- a/mne/viz/raw.py +++ b/mne/viz/raw.py @@ -587,7 +587,7 @@ def plot_raw_psd_topo( A matplotlib-compatible color to use for the axis background. Defaults to black. %(axes_spectrum_plot_topo)s - block : bool + block : bool | None This parameter is deprecated and will be removed in MNE 1.15; blocking now follows Matplotlib's behavior (see ``show``). %(show)s From 792e2a99bcba95963c0310557421325e3b49376e Mon Sep 17 00:00:00 2001 From: Clemens Brunner Date: Sat, 25 Jul 2026 10:44:47 +0200 Subject: [PATCH 4/5] Fix docdict --- mne/utils/docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/utils/docs.py b/mne/utils/docs.py index e6903a8f53b..1d9797f4da2 100644 --- a/mne/utils/docs.py +++ b/mne/utils/docs.py @@ -4268,7 +4268,7 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75): Show the figure if ``True``. When shown, blocking follows :func:`matplotlib.pyplot.show`: the call blocks until the window is closed unless Matplotlib's interactive mode is on (enabled with :func:`matplotlib.pyplot.ion` or - IPython's ``%matplotlib`` magic command), in which case it returns immediately. + IPython's ``%%matplotlib`` magic command), in which case it returns immediately. Interactive mode is off by default, so a plain script or REPL blocks. Pass ``show=False`` to build several figures and display them together with a single :func:`matplotlib.pyplot.show` call. From 27b5a5bbd3b972cbd966121abc2dbb6e6e26f7af Mon Sep 17 00:00:00 2001 From: Clemens Brunner Date: Sat, 25 Jul 2026 12:16:53 +0200 Subject: [PATCH 5/5] Remove cross-reference to legacy function --- doc/changes/dev/14098.apichange.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changes/dev/14098.apichange.rst b/doc/changes/dev/14098.apichange.rst index 5ee68306a23..28d880c42bd 100644 --- a/doc/changes/dev/14098.apichange.rst +++ b/doc/changes/dev/14098.apichange.rst @@ -1 +1 @@ -The ``block`` parameter of :meth:`mne.time_frequency.Spectrum.plot_topo`, the legacy ``plot_psd_topo`` methods, and :func:`mne.viz.plot_raw_psd_topo` is deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib's blocking behavior, by `Clemens Brunner`_. +The ``block`` parameter of :meth:`mne.time_frequency.Spectrum.plot_topo`, the legacy ``plot_psd_topo`` methods, and ``mne.viz.plot_raw_psd_topo`` is deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib's blocking behavior, by `Clemens Brunner`_.