Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 05bd0c3

Browse filesBrowse files
committed
remove unused '_save_seq' data attribute in 'FuncAnimation' class. fixes #8528.
1 parent e5d5d40 commit 05bd0c3
Copy full SHA for 05bd0c3

File tree

Expand file treeCollapse file tree

2 files changed

+61
-42
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+61
-42
lines changed

‎lib/matplotlib/animation.py

Copy file name to clipboardExpand all lines: lib/matplotlib/animation.py
+19-42Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,49 +1661,34 @@ def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
16611661

16621662
self._init_func = init_func
16631663

1664-
# Needs to be initialized so the draw functions work without checking
1665-
self._save_seq = []
1666-
16671664
TimedAnimation.__init__(self, fig, **kwargs)
16681665

1669-
# Need to reset the saved seq, since right now it will contain data
1670-
# for a single frame from init, which is not what we want.
1671-
self._save_seq = []
1672-
16731666
def new_frame_seq(self):
16741667
# Use the generating function to generate a new frame sequence
16751668
return self._iter_gen()
16761669

16771670
def new_saved_frame_seq(self):
1678-
# Generate an iterator for the sequence of saved data. If there are
1679-
# no saved frames, generate a new frame sequence and take the first
1680-
# save_count entries in it.
1681-
if self._save_seq:
1682-
# While iterating we are going to update _save_seq
1683-
# so make a copy to safely iterate over
1684-
self._old_saved_seq = list(self._save_seq)
1685-
return iter(self._old_saved_seq)
1671+
# Generate a new frame sequence
1672+
# and take the first save_count entries in it.
1673+
if self.save_count is not None:
1674+
return itertools.islice(self.new_frame_seq(), self.save_count)
16861675
else:
1687-
if self.save_count is not None:
1688-
return itertools.islice(self.new_frame_seq(), self.save_count)
1676+
frame_seq = self.new_frame_seq()
16891677

1690-
else:
1691-
frame_seq = self.new_frame_seq()
1692-
1693-
def gen():
1694-
try:
1695-
for _ in range(100):
1696-
yield next(frame_seq)
1697-
except StopIteration:
1698-
pass
1699-
else:
1700-
cbook.warn_deprecated(
1701-
"2.2", "FuncAnimation.save has truncated your "
1702-
"animation to 100 frames. In the future, no such "
1703-
"truncation will occur; please pass 'save_count' "
1704-
"accordingly.")
1705-
1706-
return gen()
1678+
def gen():
1679+
try:
1680+
for _ in range(100):
1681+
yield next(frame_seq)
1682+
except StopIteration:
1683+
pass
1684+
else:
1685+
cbook.warn_deprecated(
1686+
"2.2", "FuncAnimation.save has truncated your "
1687+
"animation to 100 frames. In the future, no such "
1688+
"truncation will occur; please pass 'save_count' "
1689+
"accordingly.")
1690+
1691+
return gen()
17071692

17081693
def _init_draw(self):
17091694
# Initialize the drawing either using the given init_func or by
@@ -1721,16 +1706,8 @@ def _init_draw(self):
17211706
'sequence of Artist objects.')
17221707
for a in self._drawn_artists:
17231708
a.set_animated(self._blit)
1724-
self._save_seq = []
17251709

17261710
def _draw_frame(self, framedata):
1727-
# Save the data for potential saving of movies.
1728-
self._save_seq.append(framedata)
1729-
1730-
# Make sure to respect save_count (keep only the last save_count
1731-
# around)
1732-
self._save_seq = self._save_seq[-self.save_count:]
1733-
17341711
# Call the func with framedata and args. If blitting is desired,
17351712
# func needs to return a sequence of any artists that were modified.
17361713
self._drawn_artists = self._func(framedata, *self._args)

‎lib/matplotlib/tests/test_animation.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_animation.py
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
from pathlib import Path
33
import sys
4+
import weakref
45

56
import numpy as np
67
import pytest
@@ -260,3 +261,44 @@ def test_failing_ffmpeg(tmpdir, monkeypatch):
260261
make_animation().save("test.mpeg")
261262
finally:
262263
animation.writers.reset_available_writers()
264+
265+
266+
def test_funcanimation_do_not_hold_references_to_frames():
267+
fig, ax = plt.subplots()
268+
line, = ax.plot([], [])
269+
270+
class Frame(dict):
271+
# this subclassing enables to use weakref.ref()
272+
pass
273+
274+
def init():
275+
line.set_data([], [])
276+
return line,
277+
278+
def animate(frame):
279+
line.set_data(frame['x'], frame['y'])
280+
return line,
281+
282+
frames_generated = []
283+
284+
def frames_generator():
285+
for _ in range(5):
286+
x = np.linspace(0, 10, 100)
287+
y = np.random.rand(100)
288+
289+
frame = Frame(x=x, y=y)
290+
291+
# collect weak references to frames
292+
# to validate their references later
293+
frames_generated.append(weakref.ref(frame))
294+
295+
yield frame
296+
297+
anim = animation.FuncAnimation(fig, animate, init_func=init,
298+
frames=frames_generator, save_count=5)
299+
300+
writer = NullMovieWriter()
301+
anim.save('unused.null', writer=writer)
302+
303+
for f in frames_generated:
304+
assert f() is None

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.