Title: [Bug]: fig.savefig throws error after radiobutton axes is removed · Issue #30325 · matplotlib/matplotlib · GitHub
Open Graph Title: [Bug]: fig.savefig throws error after radiobutton axes is removed · Issue #30325 · matplotlib/matplotlib
X Title: [Bug]: fig.savefig throws error after radiobutton axes is removed · Issue #30325 · matplotlib/matplotlib
Description: Bug summary If I create a figure with a radiobutton widget and then remove the radio widget axes in order to save the figure without the radiobutton box shown it throws an error in fig.savefig Code for reproduction import numpy as np imp...
Open Graph Description: Bug summary If I create a figure with a radiobutton widget and then remove the radio widget axes in order to save the figure without the radiobutton box shown it throws an error in fig.savefig Code...
X Description: Bug summary If I create a figure with a radiobutton widget and then remove the radio widget axes in order to save the figure without the radiobutton box shown it throws an error in fig.savefig Code...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/30325
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[Bug]: fig.savefig throws error after radiobutton axes is removed","articleBody":"### Bug summary\n\nIf I create a figure with a radiobutton widget and then remove the radio widget axes in order to save the figure without the radiobutton box shown it throws an error in fig.savefig\n\n### Code for reproduction\n\n```Python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.widgets import RadioButtons\n\n# data creation\nx = np.arange(0.0, 3.0, 0.01)\ny = np.sin(2*np.pi*x)\n\n# plotting data\nfig, ax = plt.subplots()\nl, = ax.plot(x, y)\nplt.subplots_adjust(left = 0.3)\n\n# creating radio buttons\nrax = plt.axes([0.05, 0.5, 0.15, 0.30])\nradio = RadioButtons(\n rax, labels = ['red', 'blue', 'green'], active=2, activecolor='black')\nl.set_color(radio.value_selected)\n\ndef color(label):\n l.set_color(label)\n fig.canvas.draw()\n\nradio.on_clicked(color)\n\nplt.show()\n\n# remove radio buttons axes\nradio.ax.remove()\n\nfig.tight_layout()\nfig.savefig('figure.png')\n```\n\n### Actual outcome\n\nTraceback (most recent call last):\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/cbook.py\", line 298, in process\n func(*args, **kwargs)\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/widgets.py\", line 1665, in _clear\n if self.ignore(event) or self.canvas.is_saving():\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/widgets.py\", line 120, in \u003clambda\u003e\n canvas = property(lambda self: self.ax.figure.canvas)\nAttributeError: 'NoneType' object has no attribute 'canvas'\nTraceback (most recent call last):\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/cbook.py\", line 298, in process\n func(*args, **kwargs)\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/widgets.py\", line 1665, in _clear\n if self.ignore(event) or self.canvas.is_saving():\n File \"/nfs/chess/user/rv43/miniforge3/envs/CHAP_tomo/lib/python3.10/site-packages/matplotlib/widgets.py\", line 120, in \u003clambda\u003e\n canvas = property(lambda self: self.ax.figure.canvas)\nAttributeError: 'NoneType' object has no attribute 'canvas'\n\n\n### Expected outcome\n\nThis example does produce the correct figure (one with a tight layout and no radiobuttons box), since the error that is thrown is caught by matplotlib and only printed as a warning.\n\n### Additional information\n\nIn matplotlib/widgets.py:\nReplacing:\n def _clear(self, event):\n \"\"\"Internal event handler to clear the buttons.\"\"\"\n if self.ignore(event) or self.canvas.is_saving():\n return\n self._background = self.canvas.copy_from_bbox(self.ax.bbox)\n self.ax.draw_artist(self._buttons)\nWith:\n def _clear(self, event):\n \"\"\"Internal event handler to clear the buttons.\"\"\"\n if self.ax._stale or self.ignore(event) or self.canvas.is_saving():\n return\n self._background = self.canvas.copy_from_bbox(self.ax.bbox)\n self.ax.draw_artist(self._buttons)\nSuppresses the issue, but I'm not sure if that is the desired fix or if self.ax._stale has another purpose. I have not tested CheckButtons widgets, but I'm wondering if the same happens there.\n\nIt may be wrapped up in self.ignore(event) by setting self.active = False when the radiobuttons get removed, but I don't know if that has other side effects.\n\n### Operating system\n\nScientific Linux 7, AlmaLinux-9\n\n### Matplotlib Version\n\n3.9.2, 3.10.3\n\n### Matplotlib Backend\n\nqtagg\n\n### Python version\n\n3.10.18\n\n### Jupyter version\n\nN/A\n\n### Installation\n\nconda","author":{"url":"https://github.com/rolfverberg","@type":"Person","name":"rolfverberg"},"datePublished":"2025-07-17T16:23:47.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":7},"url":"https://github.com/30325/matplotlib/issues/30325"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:52ec1520-4008-790a-f379-86a8d63e8727 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 9B32:1B675D:C418B4:1065E95:6A5321F7 |
| html-safe-nonce | 471b78ecceb2a24786093b836d22f944711257fe7fadd65c7d0956ccc32905d1 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5QjMyOjFCNjc1RDpDNDE4QjQ6MTA2NUU5NTo2QTUzMjFGNyIsInZpc2l0b3JfaWQiOiI1MTIxNDIwMjEyMTQzNTk2MDIzIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | d6217eb55c0e433b1159b9bc729e9b9a688c06a068c60b9ee662888e73ae288e |
| hovercard-subject-tag | issue:3240173862 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/matplotlib/matplotlib/30325/issue_layout |
| twitter:image | https://opengraph.githubassets.com/ef672502c74149e6ab2def365355735d0ed7b9c5f9515a1dfffeea4ae4e33b6c/matplotlib/matplotlib/issues/30325 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/ef672502c74149e6ab2def365355735d0ed7b9c5f9515a1dfffeea4ae4e33b6c/matplotlib/matplotlib/issues/30325 |
| og:image:alt | Bug summary If I create a figure with a radiobutton widget and then remove the radio widget axes in order to save the figure without the radiobutton box shown it throws an error in fig.savefig Code... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | rolfverberg |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/matplotlib/matplotlib git https://github.com/matplotlib/matplotlib.git |
| octolytics-dimension-user_id | 215947 |
| octolytics-dimension-user_login | matplotlib |
| octolytics-dimension-repository_id | 1385122 |
| octolytics-dimension-repository_nwo | matplotlib/matplotlib |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1385122 |
| octolytics-dimension-repository_network_root_nwo | matplotlib/matplotlib |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 07a982c1d40157c619b364352b704c3ce66bb332 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width