Skip to content

[Bug]: AttributeError: 'NoneType' object has no attribute 'dpi' after drawing and removing contours inside artist #21569

@astrofrog

Description

@astrofrog

Bug summary

I am running into issues with removing contour lines with Matplotlib 3.5.0rc1 - this worked with previous stable versions of Matplotlib, so it is a regression. I think this started failing with #19623.

The bug is triggered when contour lines are added and removed inside an artist. The example code below may appear a little convoluted, but it represents how the contours are drawn in WCSAxes, and the error happens the second time the figure is saved (once the contours have been removed and re-added).

Using objgraph reveals that after the contour lines are removed from the plot, there are residual references to the original PathCollection objects which are causing them to be drawn, but since .figure is no longer set on them, the code crashes.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.artist import Artist


class WCSAxesArtist(Artist):
    def draw(self, renderer, *args, **kwargs):
        if hasattr(self, '_cset') and self._cset:
            for line in self._cset.collections:
                line.remove()
        self._cset = self.axes.contour(np.arange(100).reshape(10, 10), levels=[50])


fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
artist = WCSAxesArtist()
ax.add_artist(artist)
plt.savefig('test.png')
plt.savefig('test.png')

Actual outcome

An error occurs the second time the figure is saved:

Traceback (most recent call last):
  File "/Users/tom/Dropbox/Code/Astropy/astropy/debug.py", line 19, in <module>
    plt.savefig('test.png')
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/pyplot.py", line 958, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/figure.py", line 3012, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/backend_bases.py", line 2309, in print_figure
    result = print_method(
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/backend_bases.py", line 1643, in wrapper
    return func(*args, **kwargs)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/_api/deprecation.py", line 412, in wrapper
    return func(*inner_args, **inner_kwargs)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 538, in print_png
    FigureCanvasAgg.draw(self)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 434, in draw
    self.figure.draw(self.renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/artist.py", line 73, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/figure.py", line 2803, in draw
    mimage._draw_list_compositing_images(
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 3082, in draw
    mimage._draw_list_compositing_images(
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/tom/python/dev/lib/python3.9/site-packages/matplotlib/collections.py", line 976, in draw
    self.set_sizes(self._sizes, self.figure.dpi)
AttributeError: 'NoneType' object has no attribute 'dpi'

Expected outcome

No console output

Operating system

MacOS X

Matplotlib Version

3.5.0rc1

Matplotlib Backend

Agg

Python version

3.9.7

Jupyter version

No response

Other libraries

No response

Installation

pip

Conda channel

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions