Repository navigation
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.status: confirmed bug
Milestone
Description
As of #29855 (according to git bisect) on nightly wheels in MNE-Python we now see:
_____________________ test_plot_raw_selection[matplotlib] ______________________
mne/viz/tests/test_raw.py:418: in test_plot_raw_selection
fig._fake_keypress(sel_fig.mne.close_key, fig=sel_fig)
mne/viz/_mpl_figure.py:2249: in _fake_keypress
_fake_keypress(fig, key)
mne/viz/utils.py:813: in _fake_keypress
fig.canvas.callbacks.process(
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/matplotlib/cbook.py:365: in process
func(*args, **kwargs)
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/matplotlib/widgets.py:2338: in on_key_press
self.clear()
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/matplotlib/widgets.py:2383: in clear
self.update()
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/matplotlib/widgets.py:2240: in update
self.canvas.restore_region(self.background)
^^^^^^^^^^^^^^^^^^^^^^^^^^
E AttributeError: 'FigureCanvasBase' object has no attribute 'restore_region'
Locally I can see:
../matplotlib/lib/matplotlib/widgets.py:2221: in update
self.canvas.restore_region(self.background)
E AttributeError: 'FigureCanvasBase' object has no attribute 'restore_region'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PDB post_mortem (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /home/larsoner/python/matplotlib/lib/matplotlib/widgets.py(2221)update()
-> self.canvas.restore_region(self.background)
(Pdb) p type(self)
<class 'matplotlib.widgets.LassoSelector'>
(Pdb) p self.canvas
<matplotlib.backend_bases.FigureCanvasBase object at 0x7f47ede5ca50>
(Pdb) u
(Pdb) u
(Pdb) u
(Pdb) u
> /home/larsoner/python/mne-python/mne/viz/utils.py(813)_fake_keypress()
-> fig.canvas.callbacks.process(
(Pdb) p fig
<MNESelectionFigure size 300x700 with 3 Axes>
MNESelectionFigure subclasses MNEFigure which subclasses matplotlib.figure.Figure.
I'm hoping this is enough to see the problem and know the solution. But if not, let me know and I'll take the time to whittle this down to a MWE! There might also be some way we are misusing/simulating keypresses in tests or something, but we haven't changed that code in years AFAIK so if this breaks things for us I wouldn't be surprised if it breaks things for others, too.
Metadata
Metadata
Assignees
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.status: confirmed bug
Activity
[-][Bug]: Regression in widget behavion[/-][+][Bug]: Regression in widget behavior[/+]timhoffm commentedon Sep 17, 2025
This is what we describe in the What's New entry:
and tracked in #30503.
The first failing tests fails on this line: https://github.com/mne-tools/mne-python/blob/662fb510097e38667a342e41fa525330154c5f74/mne/viz/tests/test_raw.py#L418
From a quick look, I think you code is valid and a proper fix must be on our side. As a workaround, you could set
useblit=Falseon the widgets in your test - I assume they do not really depend on active blitting.tacaswell commentedon Sep 25, 2025
I'm curious how you are getting a figure in this state. Did we get lazier about giving the figure a "real" canvas or are you testing on a figure that pyplot thinks is closed?
tacaswell commentedon Sep 25, 2025
3.11 can't go out till we fix this.
tacaswell commentedon Sep 25, 2025
(sorry, I think I pushed the wrong comment button)
timhoffm commentedon Sep 26, 2025
Sorry, I don't have time for a full debugging session right now.
The figure is created here via pyplot:
https://github.com/mne-tools/mne-python/blob/3e29187ce3a2a63b4497dc83d30869ad33ecd1be/mne/viz/_mpl_figure.py#L2360
At some point in the process later, the canvas must have been swapped out.
larsoner commentedon Sep 26, 2025
You're right! If I add a
print(fig.canvas)below the creation line I see:and running
Notably if I add some asserts:
I still hit the failure line, the
fig._fake_keypress(key=fig.mne.close_key). So it's while it's in the process of being closed that this appears to be an issue. (If I disable blitting, theassertaboutFigureCanvasBase, previously unreachable, passes.)MNT: Make useblit a property in Widget classes
tacaswell commentedon Sep 26, 2025
oh 🤦🏻 it took me far too long to notice that the key-press you are testing is what is closing the figure.
Upgrading
widget.useblitto be a property may be an easier short-term solution, I have a draft PR up.It also occurs to me that this brings up a related problem that if you set
up the widgets when you have canvas that does not support blitting but later promote it to one that does we will not blit like the user asked, but that is a later problem.
larsoner commentedon Jan 5, 2026
@timhoffm I still experience a variant of this on latest
mainon mne-tools/mne-python#13569 which removes our workaround:gives:
Traceback
Maybe this one should be reopened?
timhoffm commentedon Jan 15, 2026
@larsoner please cross-check that #30945 has now fixed your test.
larsoner commentedon Jan 16, 2026
Still failing, but the traceback is at least different now:
In particular before it ended with
Now it ends with
QuLogic commentedon Jan 17, 2026
Are you able to distill a simple test case for this? We seem to be playing whack-a-mole on this.
timhoffm commentedon Jan 17, 2026
Note: I briefly tried to install dev versions of matplotlib and mne-tools for debugging the last issue, but failed with some meson error. Certainly solvable, but ...
If we have a whack-a-mole here, that means we don't have enough oversight / control on the topic. More generally, I'm starting to get some architectural concerns. These attribute errors come from us switching the canvas back to
FigureCanvasBaseandFigureCanvasBaseobviously does not have the respective methods. So, is FigureCanvasBase the right class at all? Apparently it's an incomplete class that does not allow rendering. It is the default however, when we instantiate a default Figure() - so this not a new state, it's only new that we can come back to this state. I'm unclear whether that is reasonable.I see potentially three routes forward:
FigureCanvasBaseso that it provides the full API, but with no-ops.On an additional note, this is in RadioButtons, and I do not fully understand its drawing/blitting logic yet. There's the possibility that it has some logical quirks.
timhoffm commentedon Jan 22, 2026
@larsoner I believe the issue is now in your
SelectFromCollection. You hold a reference to the canvas athttps://github.com/mne-tools/mne-python/blob/db089c9353c7cb549d090fb47ca05c0d5bbeeb21/mne/viz/utils.py#L1659
this is used e.g. in https://github.com/mne-tools/mne-python/blob/db089c9353c7cb549d090fb47ca05c0d5bbeeb21/mne/viz/utils.py#L1780
and may cause an inconsistent state as we may have switched out the canvas. Please do not hold a reference to the canvas, but always retrieve it from the figure (
self.fig.canvas).I don't fully oversee whether that fixes everything, but it's for sure a step in the right direction.
larsoner commentedon Jan 23, 2026
@tacaswell was kind enough to fix in mne-tools/mne-python#13606, thanks for everyone's help on this one!