@@ -1069,7 +1069,7 @@ def func(current_frame: int, total_frames: int) -> Any
1069
1069
frame_number = 0
1070
1070
# TODO: Currently only FuncAnimation has a save_count
1071
1071
# attribute. Can we generalize this to all Animations?
1072
- save_count_list = [getattr (a , 'save_count ' , None )
1072
+ save_count_list = [getattr (a , '_save_count ' , None )
1073
1073
for a in all_anim ]
1074
1074
if None in save_count_list :
1075
1075
total_frames = None
@@ -1222,7 +1222,7 @@ def to_html5_video(self, embed_limit=None):
1222
1222
This saves the animation as an h264 video, encoded in base64
1223
1223
directly into the HTML5 video tag. This respects :rc:`animation.writer`
1224
1224
and :rc:`animation.bitrate`. This also makes use of the
1225
- `` interval`` to control the speed, and uses the `` repeat``
1225
+ * interval* to control the speed, and uses the * repeat*
1226
1226
parameter to decide whether to loop.
1227
1227
1228
1228
Parameters
@@ -1285,7 +1285,7 @@ def to_html5_video(self, embed_limit=None):
1285
1285
options = ['controls' , 'autoplay' ]
1286
1286
1287
1287
# If we're set to repeat, make it loop
1288
- if hasattr (self , 'repeat' ) and self . repeat :
1288
+ if getattr (self , '_repeat' , False ) :
1289
1289
options .append ('loop' )
1290
1290
1291
1291
return VIDEO_TAG .format (video = self ._base64_video ,
@@ -1306,17 +1306,18 @@ def to_jshtml(self, fps=None, embed_frames=True, default_mode=None):
1306
1306
embed_frames : bool, optional
1307
1307
default_mode : str, optional
1308
1308
What to do when the animation ends. Must be one of ``{'loop',
1309
- 'once', 'reflect'}``. Defaults to ``'loop'`` if ``self. repeat``
1310
- is True, otherwise ``'once'``.
1309
+ 'once', 'reflect'}``. Defaults to ``'loop'`` if the * repeat*
1310
+ parameter is True, otherwise ``'once'``.
1311
1311
"""
1312
1312
if fps is None and hasattr (self , '_interval' ):
1313
1313
# Convert interval in ms to frames per second
1314
1314
fps = 1000 / self ._interval
1315
1315
1316
1316
# If we're not given a default mode, choose one base on the value of
1317
- # the repeat attribute
1317
+ # the _repeat attribute
1318
1318
if default_mode is None :
1319
- default_mode = 'loop' if self .repeat else 'once'
1319
+ default_mode = 'loop' if getattr (self , '_repeat' ,
1320
+ False ) else 'once'
1320
1321
1321
1322
if not hasattr (self , "_html_representation" ):
1322
1323
# Can't open a NamedTemporaryFile twice on Windows, so use a
@@ -1380,13 +1381,12 @@ class TimedAnimation(Animation):
1380
1381
blit : bool, default: False
1381
1382
Whether blitting is used to optimize drawing.
1382
1383
"""
1383
-
1384
1384
def __init__ (self , fig , interval = 200 , repeat_delay = 0 , repeat = True ,
1385
1385
event_source = None , * args , ** kwargs ):
1386
1386
self ._interval = interval
1387
1387
# Undocumented support for repeat_delay = None as backcompat.
1388
1388
self ._repeat_delay = repeat_delay if repeat_delay is not None else 0
1389
- self .repeat = repeat
1389
+ self ._repeat = repeat
1390
1390
# If we're not given an event source, create a new timer. This permits
1391
1391
# sharing timers between animation objects for syncing animations.
1392
1392
if event_source is None :
@@ -1403,7 +1403,7 @@ def _step(self, *args):
1403
1403
# back.
1404
1404
still_going = super ()._step (* args )
1405
1405
if not still_going :
1406
- if self .repeat :
1406
+ if self ._repeat :
1407
1407
# Restart the draw loop
1408
1408
self ._init_draw ()
1409
1409
self .frame_seq = self .new_frame_seq ()
@@ -1423,6 +1423,8 @@ def _step(self, *args):
1423
1423
self .event_source .interval = self ._interval
1424
1424
return True
1425
1425
1426
+ repeat = _api .deprecated ("3.7" )(property (lambda self : self ._repeat ))
1427
+
1426
1428
1427
1429
class ArtistAnimation (TimedAnimation ):
1428
1430
"""
@@ -1564,7 +1566,7 @@ def init_func() -> iterable_of_artists
1564
1566
fargs : tuple or None, optional
1565
1567
Additional arguments to pass to each call to *func*.
1566
1568
1567
- save_count : int, default: 100
1569
+ save_count : int, optional
1568
1570
Fallback for the number of values from *frames* to cache. This is
1569
1571
only used if the number of frames cannot be inferred from *frames*,
1570
1572
i.e. when it's an iterator without length or a generator.
@@ -1589,7 +1591,6 @@ def init_func() -> iterable_of_artists
1589
1591
Whether frame data is cached. Disabling cache might be helpful when
1590
1592
frames contain large objects.
1591
1593
"""
1592
-
1593
1594
def __init__ (self , fig , func , frames = None , init_func = None , fargs = None ,
1594
1595
save_count = None , * , cache_frame_data = True , ** kwargs ):
1595
1596
if fargs :
@@ -1602,7 +1603,7 @@ def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
1602
1603
# Amount of framedata to keep around for saving movies. This is only
1603
1604
# used if we don't know how many frames there will be: in the case
1604
1605
# of no generator or in the case of a callable.
1605
- self .save_count = save_count
1606
+ self ._save_count = save_count
1606
1607
# Set up a function that creates a new iterable when needed. If nothing
1607
1608
# is passed in for frames, just use itertools.count, which will just
1608
1609
# keep counting from 0. A callable passed in for frames is assumed to
@@ -1622,19 +1623,10 @@ def iter_frames(frames=frames):
1622
1623
else :
1623
1624
self ._iter_gen = lambda : iter (frames )
1624
1625
if hasattr (frames , '__len__' ):
1625
- self .save_count = len (frames )
1626
+ self ._save_count = len (frames )
1626
1627
else :
1627
1628
self ._iter_gen = lambda : iter (range (frames ))
1628
- self .save_count = frames
1629
-
1630
- if self .save_count is None :
1631
- # If we're passed in and using the default, set save_count to 100.
1632
- self .save_count = 100
1633
- else :
1634
- # itertools.islice returns an error when passed a numpy int instead
1635
- # of a native python int (https://bugs.python.org/issue30537).
1636
- # As a workaround, convert save_count to a native python int.
1637
- self .save_count = int (self .save_count )
1629
+ self ._save_count = frames
1638
1630
1639
1631
self ._cache_frame_data = cache_frame_data
1640
1632
@@ -1661,26 +1653,18 @@ def new_saved_frame_seq(self):
1661
1653
self ._old_saved_seq = list (self ._save_seq )
1662
1654
return iter (self ._old_saved_seq )
1663
1655
else :
1664
- if self .save_count is not None :
1665
- return itertools .islice (self .new_frame_seq (), self .save_count )
1666
-
1667
- else :
1656
+ if self ._save_count is None :
1668
1657
frame_seq = self .new_frame_seq ()
1669
1658
1670
1659
def gen ():
1671
1660
try :
1672
- for _ in range ( 100 ) :
1661
+ while True :
1673
1662
yield next (frame_seq )
1674
1663
except StopIteration :
1675
1664
pass
1676
- else :
1677
- _api .warn_deprecated (
1678
- "2.2" , message = "FuncAnimation.save has truncated "
1679
- "your animation to 100 frames. In the future, no "
1680
- "such truncation will occur; please pass "
1681
- "'save_count' accordingly." )
1682
-
1683
1665
return gen ()
1666
+ else :
1667
+ return itertools .islice (self .new_frame_seq (), self ._save_count )
1684
1668
1685
1669
def _init_draw (self ):
1686
1670
super ()._init_draw ()
@@ -1721,7 +1705,8 @@ def _draw_frame(self, framedata):
1721
1705
1722
1706
# Make sure to respect save_count (keep only the last save_count
1723
1707
# around)
1724
- self ._save_seq = self ._save_seq [- self .save_count :]
1708
+ if self ._save_count is not None :
1709
+ self ._save_seq = self ._save_seq [- self ._save_count :]
1725
1710
1726
1711
# Call the func with framedata and args. If blitting is desired,
1727
1712
# func needs to return a sequence of any artists that were modified.
@@ -1747,3 +1732,6 @@ def _draw_frame(self, framedata):
1747
1732
1748
1733
for a in self ._drawn_artists :
1749
1734
a .set_animated (self ._blit )
1735
+
1736
+ save_count = _api .deprecated ("3.7" )(
1737
+ property (lambda self : self ._save_count ))
0 commit comments