Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Bug]: Artist.remove() isn't fully removing it from figure #25572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
raamana opened this issue Mar 29, 2023 · 5 comments · May be fixed by #25573
Open

[Bug]: Artist.remove() isn't fully removing it from figure #25572

raamana opened this issue Mar 29, 2023 · 5 comments · May be fixed by #25573

Comments

@raamana
Copy link
Contributor

raamana commented Mar 29, 2023

Bug summary

I am trying to remove some artists (RadioButtons and CheckButtons) while keeping some others (axes with images), before exporting a figure to disk, and am running into this error:
AttributeError: 'NoneType' object has no attribute 'canvas'

as MPL is trying to check if canvas for RadioButton has changed, although that RadioButton should not part of the equation at all as it was removed prior to trying to .savefig()

Code for reproduction

import matplotlib.pyplot as plt

from matplotlib.widgets import RadioButtons

fig, ax = plt.subplots(1, 1)

radio = RadioButtons(ax, ['1', '2'], 0)

radio.ax.remove()

fig.savefig('~/Downloads/saved_after_artist_remove.png')

Actual outcome

Traceback (most recent call last):
  File "/Users/Reddy/dev/visualqc/visualqc/tests/artist_remove.py", line 12, in <module>
    fig.savefig('~/Downloads/saved_after_artist_remove.png')
  File "/usr/local/lib/python3.11/site-packages/matplotlib/figure.py", line 3343, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backend_bases.py", line 2366, in print_figure
    result = print_method(
             ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backend_bases.py", line 2232, in <lambda>
    print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
                                                                 ^^^^^
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 509, in print_png
    self._print_pil(filename_or_obj, "png", pil_kwargs, metadata)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 457, in _print_pil
    FigureCanvasAgg.draw(self)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 400, in draw
    self.figure.draw(self.renderer)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/artist.py", line 95, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/matplotlib/figure.py", line 3150, in draw
    DrawEvent("draw_event", self.canvas, renderer)._process()
  File "/usr/local/lib/python3.11/site-packages/matplotlib/backend_bases.py", line 1263, in _process
    self.canvas.callbacks.process(self.name, self)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/cbook/__init__.py", line 309, in process
    self.exception_handler(exc)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/cbook/__init__.py", line 96, in _exception_printer
    raise exc
  File "/usr/local/lib/python3.11/site-packages/matplotlib/cbook/__init__.py", line 304, in process
    func(*args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/matplotlib/widgets.py", line 1719, in _clear
    if self.ignore(event) or self._changed_canvas():
                             ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/matplotlib/widgets.py", line 107, in _changed_canvas
    return self.canvas is not self.ax.figure.canvas
                              ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'canvas'

Expected outcome

smooth export with no error

Additional information

No response

Operating system

macOS 13

Matplotlib Version

3.7.1

Matplotlib Backend

TkAgg

Python version

3.11

Jupyter version

No response

Installation

pip

@raamana
Copy link
Contributor Author

raamana commented Mar 29, 2023

likely related to this 2015 comment from @tacaswell : Apparently the remove is not doing enough clean up: #5663

@QuLogic
Copy link
Member

QuLogic commented Mar 29, 2023

At the moment, I think you can workaround this by calling radio.disconnect_events() before removing the Axes.

@tacaswell tacaswell added this to the v3.7.2 milestone Mar 29, 2023
@Higgs32584
Copy link
Contributor

This is likely related to #25274, although this is likely different enough to warrant its own issue. The legend appears to be unstable right now.

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 29, 2023
@tacaswell
Copy link
Member

I do not think this is related to #25274 as in that case the Container is still in the list of containers however in this case the issue is that there is a dangling callback that was not cleared.

@raamana
Copy link
Contributor Author

raamana commented Mar 29, 2023

At the moment, I think you can workaround this by calling radio.disconnect_events() before removing the Axes.

that helped. thanks everyone!

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 31, 2023
@QuLogic QuLogic modified the milestones: v3.7.2, v3.7.3 Jul 5, 2023
@QuLogic QuLogic modified the milestones: v3.7.3, v3.8.0 Sep 9, 2023
@ksunden ksunden removed this from the v3.8.0 milestone Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants