Skip to content

FIX: Prevent crash when removing a subfigure containing subplots#31323

Open
Vikash-Kumar-23 wants to merge 2 commits intomatplotlib:mainfrom
Vikash-Kumar-23:fix-subfigure-remove-31319
Open

FIX: Prevent crash when removing a subfigure containing subplots#31323
Vikash-Kumar-23 wants to merge 2 commits intomatplotlib:mainfrom
Vikash-Kumar-23:fix-subfigure-remove-31319

Conversation

@Vikash-Kumar-23
Copy link

Closes #31319

## PR summary
This PR fixes a crash reported in #31319 that occurs when removing a subfigure after creating subplots inside it.

### Why is this change necessary?
Calling `.remove()` on a `SubFigure` can currently raise:
```pytb
AttributeError: 'list' object has no attribute '_mouseover_set'

This makes subfigure removal unreliable in otherwise valid figure layouts.

What problem does it solve?

It prevents Artist.remove() from attempting axes-specific mouse-hitlist cleanup when self.axes is not an actual matplotlib.axes.Axes instance (it can be a list in the subfigure-removal scenario).

What is the reasoning for this implementation?

Artist.remove() contains cleanup code that assumes self.axes is an Axes and accesses self.axes._mouseover_set. In the failing case, self.axes is a list, so accessing _mouseover_set crashes. The fix tightens the guard so this cleanup block only runs when self.axes is a non-None Axes instance.

Minimal self-contained example (repro / verification)

import matplotlib
matplotlib.use("Agg")  # for reproducibility/headless runs
import matplotlib.pyplot as plt

fig = plt.figure()
subfigs = fig.subfigures(1, 2)
subfigs[0].subplots()
subfigs[0].remove()
print("OK: no crash")

What changed (only 2 files)

  • lib/matplotlib/artist.py: Guard the _mouseover_set cleanup in Artist.remove() so it only runs when self.axes is an Axes.
  • lib/matplotlib/tests/test_figure.py: Add/update a regression test that creates subplots inside a subfigure and then removes the subfigure.

How to test locally

python -m pytest lib/matplotlib/tests/test_figure.py -k test_subfigure_remove -q

AI Disclosure

I used AI assistance to help draft the PR description and verification steps. The code changes and local verification were performed and reviewed by me.

PR checklist

  • "closes [Bug]: Crash when removing a subfigure with a subplot in a figure #31319" is in the body of the PR description to link the related issue
  • new and changed code is tested
  • [N/A] Plotting related features are demonstrated in an example
  • [N/A] New Features and API Changes are noted with a directive and release note
  • [N/A] Documentation complies with general and docstring guidelines

@github-actions
Copy link

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join us on gitter for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide.
Please let us know if (and how) you use AI, it will help us give you better feedback on your PR.

We strive to be a welcoming and open project. Please follow our Code of Conduct.

@tacaswell
Copy link
Member

Do we need to go up a layer in the inheritance tree? Will this work with the axes in mpl toolkits?

Would checking that it is not a list be a better option? Still has some edge cases, but does not introduce circular imports.

@Vikash-Kumar-23
Copy link
Author

Thanks for the feedback! I’ve updated the guard in Artist.remove() to avoid importing or type-checking against Axes.

Instead of isinstance(self.axes, Axes), it now uses an attribute-based check:

  • ax = getattr(self, "axes", None)
  • mouseover_set = getattr(ax, "_mouseover_set", None)

The cleanup now only runs when _mouseover_set is present. This avoids the crash when self.axes is a list, prevents circular import issues, and should work with toolkit/derived axes as well.

@melissawm melissawm moved this to Needs review in First Time Contributors Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs review

Development

Successfully merging this pull request may close these issues.

[Bug]: Crash when removing a subfigure with a subplot in a figure

3 participants