The Wayback Machine - https://web.archive.org/web/20230308145346/https://github.com/matplotlib/matplotlib/issues/21007
Skip to content
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

Animation was deleted without rendering anything #21007

Open
OverLordGoldDragon opened this issue Sep 6, 2021 · 4 comments
Open

Animation was deleted without rendering anything #21007

OverLordGoldDragon opened this issue Sep 6, 2021 · 4 comments

Comments

@OverLordGoldDragon
Copy link

OverLordGoldDragon commented Sep 6, 2021

Irregular warning, sometimes prints sometimes not without changing anything in code. Didn't occur in 3.3.4. It's also thrown after running an entirely different cell or file, if not restarting kernel first.

conda install --conda-forge matplotlib 3.4.3, backend module://ipykernel.pylab.backend_inline (Spyder), Windows 10, Python 3.7.9

D:\Anaconda\envs\pyt\lib\site-packages\matplotlib\animation.py:974: UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.
  'Animation was deleted without rendering anything. This is '
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class Animation(animation.TimedAnimation):
    def __init__(self):
        fig = plt.figure()
        fig.add_subplot(2, 2, 1)
        animation.TimedAnimation.__init__(self, fig, blit=True)

    def _draw_frame(self, frame_idx): pass

    def new_frame_seq(self): return iter(range(2))

ani = Animation()
ani.save('test.mp4')
@tacaswell
Copy link
Member

That is coming from

def __del__(self):
if not getattr(self, '_draw_was_started', True):
warnings.warn(
'Animation was deleted without rendering anything. This is '
'most likely not intended. To prevent deletion, assign the '
'Animation to a variable, e.g. `anim`, that exists until you '
'have outputted the Animation using `plt.show()` or '
'`anim.save()`.'
)
which expects
def _init_draw(self):
# Initial draw to clear the frame. Also used by the blitting code
# when a clean base is required.
self._draw_was_started = True
to have run at least once.

That check should be running when the object is garbage collected which if there are circular references can be deferred some amount of time (until Python decides to do a sweep for circular references). As an implementation detail of CPython, If the reference count of an object goes to 0, it is immediately dealocated, however it is is possible to have 2 objects form a ring: A hold a reference to B and B hold a reference to A (the rings can be bigger). When you lose all reference to A and B in your code you can never get them back, however due to the circular references, the refcount is still >0 so Python does not know it is safe to get rid of them. Every so often the interpreter will do the (expensive) task of finding and breaking those loops. It defines "time" via number of byte codes processed, hence this will come out some random (but bounded) time later.

@timhoffm
Copy link
Member

timhoffm commented Sep 7, 2021

Bun ani.save() should call ani._init_draw(). So the warning should not appear. Is this maybe split over multiple cells and you forgot to call ani.save()?

@tacaswell
Copy link
Member

If this is in a notebook cell, there is also still a hard ref to ani being held in the user namespace and it should not be being garbage collected!

Throwing a print(ani._draw_was_started) on the bottom of the snippet in the OP does confirm that _draw_was_started is set to True.

I suspect that the cell is being run and/or interrupted more than once? Also a bit worried that this is specific to either spyder or inline (but nothing is coming to mind as a reason why).

@OverLordGoldDragon
Copy link
Author

I ran it as a cell several times, printed True each time, but eventually threw the warning again. Cannot reproduce with runfile instead, which is closer but not identical to a kernel restart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants