29
29
import shutil
30
30
import sys
31
31
import tempfile
32
- from matplotlib .cbook import iterable , is_string_like
32
+ import warnings
33
+ from matplotlib .cbook import iterable , is_string_like , mplDeprecation
33
34
from matplotlib .compat import subprocess
34
35
from matplotlib import verbose
35
36
from matplotlib import rcParams
@@ -77,11 +78,10 @@ def __getitem__(self, name):
77
78
78
79
class MovieWriter (object ):
79
80
'''
80
- Base class for writing movies. Fundamentally, what a MovieWriter does
81
- is provide is a way to grab frames by calling grab_frame(). setup()
82
- is called to start the process and finish() is called afterwards.
83
- This class is set up to provide for writing movie frame data to a pipe.
84
- saving() is provided as a context manager to facilitate this process as::
81
+ Base class for writing movies. Fundamentally, what a MovieWriter does is
82
+ provide is a way to grab frames by calling grab_frame(). This class is set
83
+ up to provide for writing movie frame data to a pipe. saving() is provided
84
+ as a context manager to facilitate this process as::
85
85
86
86
with moviewriter.saving('myfile.mp4'):
87
87
# Iterate over frames
@@ -147,7 +147,7 @@ def frame_size(self):
147
147
width_inches , height_inches = self .fig .get_size_inches ()
148
148
return width_inches * self .dpi , height_inches * self .dpi
149
149
150
- def setup (self , fig , outfile , dpi , * args ):
150
+ def setup (self , * args , ** kwargs ):
151
151
'''
152
152
Perform setup for writing the movie file.
153
153
@@ -159,28 +159,33 @@ def setup(self, fig, outfile, dpi, *args):
159
159
The DPI (or resolution) for the file. This controls the size
160
160
in pixels of the resulting movie file.
161
161
'''
162
+ warnings .warn ('setup interacts poorly with the saving context-manager' ,
163
+ mplDeprecation )
164
+ self ._setup (* args , ** kwargs )
165
+
166
+ def _setup (self , outfile , dpi ):
162
167
self .outfile = outfile
163
168
self .fig = fig
164
169
self .dpi = dpi
165
-
166
170
# Run here so that grab_frame() can write the data to a pipe. This
167
171
# eliminates the need for temp files.
168
172
self ._run ()
169
173
170
174
@contextlib .contextmanager
171
- def saving (self , * args ):
175
+ def saving (self , * args , ** kwargs ):
172
176
'''
173
177
Context manager to facilitate writing the movie file.
174
178
175
- ``*args`` are any parameters that should be passed to `setup`.
179
+ ``*args`` and ``**kwargs`` are any parameters that should be passed to
180
+ `setup`.
176
181
'''
177
182
# This particular sequence is what contextlib.contextmanager wants
178
- self .setup (* args )
183
+ self ._setup (* args , ** kwargs )
179
184
try :
180
185
yield
181
- self .finish ()
186
+ self ._finish ()
182
187
finally :
183
- self .cleanup ()
188
+ self ._cleanup ()
184
189
185
190
def _run (self ):
186
191
# Uses subprocess to call the program for assembling frames into a
@@ -199,6 +204,12 @@ def _run(self):
199
204
200
205
def finish (self ):
201
206
'Finish any processing for writing the movie.'
207
+ warnings .warn ('finish interacts poorly with the saving context-manager' ,
208
+ mplDeprecation )
209
+ self .cleanup ()
210
+
211
+ def _finish (self ):
212
+ 'Finish any processing for writing the movie.'
202
213
203
214
def grab_frame (self , ** savefig_kwargs ):
204
215
'''
@@ -229,6 +240,12 @@ def _args(self):
229
240
return NotImplementedError ("args needs to be implemented by subclass." )
230
241
231
242
def cleanup (self ):
243
+ 'Clean-up and collect the process used to write the movie file.'
244
+ warnings .warn ('cleanup interacts poorly with the saving context-manager' ,
245
+ mplDeprecation )
246
+ self ._cleanup ()
247
+
248
+ def _cleanup (self ):
232
249
'Clean-up and collect the process used to write the movie file.'
233
250
if hasattr (self , "_proc" ):
234
251
out , err = self ._proc .communicate ()
@@ -269,8 +286,8 @@ def __init__(self, *args, **kwargs):
269
286
MovieWriter .__init__ (self , * args , ** kwargs )
270
287
self .frame_format = rcParams ['animation.frame_format' ]
271
288
272
- def setup (self , fig , outfile , dpi , frame_prefix = '_tmp' , clear_temp = True ,
273
- tmpdir = None ):
289
+ def _setup (self , fig , outfile , dpi , frame_prefix = '_tmp' , clear_temp = True ,
290
+ tmpdir = None ):
274
291
'''
275
292
Perform setup for writing the movie file.
276
293
@@ -297,12 +314,13 @@ def setup(self, fig, outfile, dpi, frame_prefix='_tmp', clear_temp=True,
297
314
self .temp_prefix = frame_prefix
298
315
self ._frame_counter = 0 # used for generating sequential file names
299
316
if tmpdir is None :
300
- self ._tmpdir = self ._temp_names = tempfile .mkdtemp ()
317
+ self ._tmpdir = tempfile .mkdtemp ()
318
+ self ._temp_names = None
301
319
else :
302
320
self ._tmpdir = tmpdir
303
321
self ._temp_names = list ()
304
- self .fname_format_str = os .path .join (
305
- self . _tmpdir . replace ( '%' , '%%' ), '%s%%07d.%s' )
322
+ self .fname_format_str = os .path .join (self . _tmpdir . replace ( '%' , '%%' ),
323
+ '%s%%07d.%s' )
306
324
307
325
@property
308
326
def frame_format (self ):
@@ -366,11 +384,11 @@ def grab_frame(self, **savefig_kwargs):
366
384
err ), level = 'helpful' )
367
385
raise
368
386
369
- def finish (self ):
387
+ def _finish (self ):
370
388
# Call run here now that all frame grabbing is done. All temp files
371
389
# are available to be assembled.
372
390
self ._run ()
373
- MovieWriter .finish (self )
391
+ MovieWriter ._finish (self )
374
392
375
393
# Check error code for creating file here, since we just run
376
394
# the process here, rather than having an open pipe.
@@ -379,20 +397,23 @@ def finish(self):
379
397
+ str (self ._proc .returncode )
380
398
+ ' Try running with --verbose-debug' )
381
399
382
- def cleanup (self ):
383
- MovieWriter .cleanup (self )
400
+ def _cleanup (self ):
401
+ MovieWriter ._cleanup (self )
384
402
385
403
#Delete temporary files
386
404
if self .clear_temp :
387
- verbose .report (
388
- 'MovieWriter: clearing temporary fnames=%s' %
389
- str (self ._temp_names ),
405
+ if self ._temp_names is None : # tmpdir created with mkdtemp
406
+ verbose .report (
407
+ 'MovieWriter: clearing temporary fnames=%s' % self ._tmpdir ,
408
+ level = 'debug' )
409
+ shutil .rmtree (self ._tmpdir )
410
+ else :
411
+ verbose .report (
412
+ 'MovieWriter: clearing temporary fnames=%s' %
413
+ self ._temp_names ,
390
414
level = 'debug' )
391
- if isinstance (self ._temp_names , list ):
392
415
for fname in self ._temp_names :
393
416
os .remove (fname )
394
- else :
395
- shutil .rmtree (self ._temp_names )
396
417
397
418
398
419
# Base class of ffmpeg information. Has the config keys and the common set
0 commit comments