Skip to content

ENH: Add block argument to stc.plot() (gh-14105) - #14185

Open
CedricConday wants to merge 2 commits into
mne-tools:mainfrom
CedricConday:enh/stc-plot-block
Open

ENH: Add block argument to stc.plot() (gh-14105)#14185
CedricConday wants to merge 2 commits into
mne-tools:mainfrom
CedricConday:enh/stc-plot-block

Conversation

@CedricConday

Copy link
Copy Markdown
Contributor

Closes #14105.

What

Adds block=False to mne.viz.plot_source_estimates, threaded through
SourceEstimate.plot and VolSourceEstimate.plot_3d.

stc.plot() returns immediately, so in a script there is no opportunity to
interact with the figure before the interpreter exits. raw.plot() has block;
this gives stc.plot() the same option.

The default is False, preserving current behaviour — generating figures in a
script or a report is the common case and must not start blocking.

Scope

Deliberately not added to VectorSourceEstimate.plot / .plot_3d, which
document from plot_vector_source_estimates. Only the two methods that share
the plot_source_estimates docstring accept it, per @cbrnr's "YAGNI and let's
just fix this one" and @larsoner's preference not to add block everywhere.

VolSourceEstimate.plot_3d had to be included because it shares that docstring
via copy_function_doc_to_method_doc — documenting the parameter without
accepting it fails test_docstring_parameters (PR02: Unknown parameters).

Implementation

The coregistration GUI already had this logic inline:

if block and self._renderer._kind != "notebook":
    _qt_app_exec(self._renderer.figure.store["app"])

Rather than copy it, it is now _qt_block in mne/viz/backends/_utils.py, and
_coreg.py calls that. So this removes a duplicate rather than adding one. The
matplotlib backend blocks through the existing plt_show(True, block=block).

Tests

  • test_qt_block_runs_event_loop — arms a QTimer that records and quits, then
    asserts the recorder ran, so an early return is caught. State-based rather
    than a wall-clock threshold, to avoid CI flakiness.
  • test_qt_block_without_qt_app — notebook backend, and a renderer whose
    plotter came from the caller, both return without attempting to block.
  • test_process_clim_plot gains a block="yes"TypeError check.

Verified locally, including end-to-end under Xvfb on the testing dataset:
stc.plot(block=True) returned after 2.55 s against a 2.5 s quit timer, with the
timer confirmed fired, and still returned a Brain. Removing the bool
validation makes stc.plot(block="yes") block forever, which is what that check
prevents. mne/viz/backends/tests/ and mne/tests/test_docstring_parameters.py
pass (29 passed, 6 skipped, 1 xfailed); ruff format and ruff check are clean.

Blocking on the notebook backend is not tested — no notebook backend available
in the environment I verified in.

AI assistance disclosure

Per CONTRIBUTING's policy on AI assistance: this contribution is AI-assisted. The
code, tests and this description were written by Claude (Anthropic), directed by
me. I set the scope, made the design calls above, reviewed the diff, and ran the
verification described. It is not the output of a fully automated tool — every
step was directed and reviewed by me before submission.

`stc.plot()` returns immediately, so running it in a script leaves no
opportunity to interact with the figure before the interpreter exits. Unlike
`raw.plot()` there was no way to ask for the call to halt until the window is
closed.

Add `block=False` to `plot_source_estimates`, and thread it through
`SourceEstimate.plot` and `VolSourceEstimate.plot_3d`, which share its
docstring. The default preserves the current non-blocking behaviour, which is
what makes the function usable for generating figures in a script or report.

Blocking reuses the mechanism the coregistration GUI already used; that code
is now shared as `_qt_block` rather than duplicated. The matplotlib backend
blocks via `plt_show`.

Closes mne-toolsgh-14105
@CedricConday
CedricConday requested a review from drammock as a code owner August 20, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stc.plot() closes when run non-interactively

1 participant