diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 36ba29d55e85..c1822df960e6 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -29,7 +29,9 @@ # * http://pymedia.org/ # * libmng (produces swf) python wrappers: https://github.com/libming/libming # * Wrap x264 API: -# http://stackoverflow.com/questions/2940671/how-to-encode-series-of-images-into-h264-using-x264-api-c-c + +# (http://stackoverflow.com/questions/2940671/ +# how-to-encode-series-of-images-into-h264-using-x264-api-c-c ) # A registry for available MovieWriter classes @@ -83,7 +85,7 @@ class MovieWriter(object): The format used in writing frame data, defaults to 'rgba' ''' def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None, - metadata=None): + metadata=None): ''' Construct a new MovieWriter object. @@ -199,11 +201,12 @@ def grab_frame(self, **savefig_kwargs): # Tell the figure to save its data to the sink, using the # frame format and dpi. self.fig.savefig(self._frame_sink(), format=self.frame_format, - dpi=self.dpi, **savefig_kwargs) + dpi=self.dpi, **savefig_kwargs) except RuntimeError: out, err = self._proc.communicate() - verbose.report('MovieWriter -- Error running proc:\n%s\n%s' % (out, - err), level='helpful') + verbose.report('MovieWriter -- Error ' + 'running proc:\n%s\n%s' % (out, + err), level='helpful') raise def _frame_sink(self): @@ -217,10 +220,10 @@ def _args(self): def cleanup(self): 'Clean-up and collect the process used to write the movie file.' out, err = self._proc.communicate() - verbose.report('MovieWriter -- Command stdout:\n%s' % out, - level='debug') - verbose.report('MovieWriter -- Command stderr:\n%s' % err, - level='debug') + verbose.report('MovieWriter -- ' + 'Command stdout:\n%s' % out, level='debug') + verbose.report('MovieWriter -- ' + 'Command stderr:\n%s' % err, level='debug') @classmethod def bin_path(cls): @@ -238,8 +241,10 @@ def isAvailable(cls): running the commandline tool. ''' try: - subprocess.Popen(cls.bin_path(), shell=False, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + subprocess.Popen(cls.bin_path(), + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) return True except OSError: return False @@ -307,7 +312,7 @@ def _frame_sink(self): self._temp_names.append(fname) verbose.report( 'FileMovieWriter.frame_sink: saving frame %d to fname=%s' % - (self._frame_counter, fname), + (self._frame_counter, fname), level='debug') self._frame_counter += 1 # Ensures each created name is 'unique' @@ -325,8 +330,8 @@ def finish(self): # the process here, rather than having an open pipe. if self._proc.returncode: raise RuntimeError('Error creating movie, return code: ' - + str(self._proc.returncode) - + ' Try running with --verbose-debug') + + str(self._proc.returncode) + + ' Try running with --verbose-debug') def cleanup(self): MovieWriter.cleanup(self) @@ -405,6 +410,7 @@ class AVConvBase(FFMpegBase): class AVConvWriter(AVConvBase, FFMpegWriter): pass + # Combine AVConv options with file-based writing @writers.register('avconv_file') class AVConvFileWriter(AVConvBase, FFMpegFileWriter): @@ -420,7 +426,7 @@ class MencoderBase: # Mencoder only allows certain keys, other ones cause the program # to fail. allowed_metadata = ['name', 'artist', 'genre', 'subject', 'copyright', - 'srcform', 'comment'] + 'srcform', 'comment'] # Mencoder mandates using name, but 'title' works better with ffmpeg. # If we find it, just put it's value into name @@ -439,8 +445,8 @@ def output_args(self): args.extend(self.extra_args) if self.metadata: args.extend(['-info', ':'.join('%s=%s' % (k, v) - for k, v in self.metadata.items() - if k in self.allowed_metadata)]) + for k, v in self.metadata.items() + if k in self.allowed_metadata)]) return args @@ -451,9 +457,9 @@ def _args(self): # Returns the command line parameters for subprocess to use # mencoder to create a movie return [self.bin_path(), '-', '-demuxer', 'rawvideo', '-rawvideo', - ('w=%i:h=%i:' % self.frame_size + - 'fps=%i:format=%s' % (self.fps, - self.frame_format))] + self.output_args + ('w=%i:h=%i:' % self.frame_size + + 'fps=%i:format=%s' % (self.fps, + self.frame_format))] + self.output_args # Combine Mencoder options with temp file-based writing @@ -465,10 +471,10 @@ def _args(self): # Returns the command line parameters for subprocess to use # mencoder to create a movie return [self.bin_path(), - 'mf://%s*.%s' % (self.temp_prefix, self.frame_format), - '-frames', str(self._frame_counter), '-mf', - 'type=%s:fps=%d' % (self.frame_format, - self.fps)] + self.output_args + 'mf://%s*.%s' % (self.temp_prefix, self.frame_format), + '-frames', str(self._frame_counter), '-mf', + 'type=%s:fps=%d' % (self.frame_format, + self.fps)] + self.output_args # Base class for animated GIFs with convert utility @@ -622,21 +628,26 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None, if savefig_kwargs is None: savefig_kwargs = {} - # FIXME: Using 'bbox_inches' doesn't currently work with writers that pipe - # the data to the command because this requires a fixed frame size (see - # Ryan May's reply in this thread: [1]). Thus we drop the 'bbox_inches' - # argument if it exists in savefig_kwargs. + # FIXME: Using 'bbox_inches' doesn't currently work with + # writers that pipe the data to the command because this + # requires a fixed frame size (see Ryan May's reply in this + # thread: [1]). Thus we drop the 'bbox_inches' argument if it + # exists in savefig_kwargs. # - # [1] http://matplotlib.1069221.n5.nabble.com/Animation-class-let-save-accept-kwargs-which-are-passed-on-to-savefig-td39627.html + # [1] (http://matplotlib.1069221.n5.nabble.com/ + # Animation-class-let-save-accept-kwargs-which- + # are-passed-on-to-savefig-td39627.html) # - if savefig_kwargs.has_key('bbox_inches'): + if 'bbox_inches' in savefig_kwargs: if not (writer in ['ffmpeg_file', 'mencoder_file'] or - isinstance(writer, (FFMpegFileWriter, MencoderFileWriter))): - print("Warning: discarding the 'bbox_inches' argument in " \ - "'savefig_kwargs' as it is only currently supported " \ - "with the writers 'ffmpeg_file' and 'mencoder_file' " \ - "(writer used: '{}').".format(writer if isinstance(writer, str) - else writer.__class__.__name__)) + isinstance(writer, + (FFMpegFileWriter, MencoderFileWriter))): + print("Warning: discarding the 'bbox_inches' argument in " + "'savefig_kwargs' as it is only currently supported " + "with the writers 'ffmpeg_file' and 'mencoder_file' " + "(writer used: " + "'{}').".format(writer if isinstance(writer, str) + else writer.__class__.__name__)) savefig_kwargs.pop('bbox_inches') # Need to disconnect the first draw callback, since we'll be doing @@ -677,7 +688,8 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None, if is_string_like(writer): if writer in writers.avail: writer = writers[writer](fps, codec, bitrate, - extra_args=extra_args, metadata=metadata) + extra_args=extra_args, + metadata=metadata) else: import warnings warnings.warn("MovieWriter %s unavailable" % writer) @@ -708,7 +720,7 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None, # Reconnect signal for first draw if necessary if reconnect_first_draw: self._first_draw_id = self._fig.canvas.mpl_connect('draw_event', - self._start) + self._start) def _step(self, *args): ''' @@ -756,7 +768,7 @@ def _pre_draw(self, framedata, blit): def _draw_frame(self, framedata): # Performs actual drawing of the frame. raise NotImplementedError('Needs to be implemented by subclasses to' - ' actually make an animation.') + ' actually make an animation.') def _post_draw(self, framedata, blit): # After the frame is rendered, this handles the actual flushing of @@ -799,7 +811,7 @@ def _setup_blit(self): self._blit_cache = dict() self._drawn_artists = [] self._resize_id = self._fig.canvas.mpl_connect('resize_event', - self._handle_resize) + self._handle_resize) self._post_draw(None, self._blit) def _handle_resize(self, *args): @@ -821,7 +833,7 @@ def _end_redraw(self, evt): self.event_source.start() self._fig.canvas.mpl_disconnect(self._resize_id) self._resize_id = self._fig.canvas.mpl_connect('resize_event', - self._handle_resize) + self._handle_resize) class TimedAnimation(Animation): @@ -836,7 +848,7 @@ class TimedAnimation(Animation): the animation. ''' def __init__(self, fig, interval=200, repeat_delay=None, repeat=True, - event_source=None, *args, **kwargs): + event_source=None, *args, **kwargs): # Store the timing information self._interval = interval self._repeat_delay = repeat_delay @@ -952,13 +964,13 @@ class FuncAnimation(TimedAnimation): *init_func* is a function used to draw a clear frame. If not given, the results of drawing from the first item in the frames sequence will be - used. This function will be called once before the first frame. + used. This function will be called once before the first frame. If blit=True, *func* and *init_func* should return an iterable of drawables to clear. ''' def __init__(self, fig, func, frames=None, init_func=None, fargs=None, - save_count=None, **kwargs): + save_count=None, **kwargs): if fargs: self._args = fargs else: diff --git a/lib/matplotlib/tests/test_coding_standards.py b/lib/matplotlib/tests/test_coding_standards.py index 664327d2134c..3ad2d6b12cc5 100644 --- a/lib/matplotlib/tests/test_coding_standards.py +++ b/lib/matplotlib/tests/test_coding_standards.py @@ -16,7 +16,6 @@ class StandardReportWithExclusions(pep8.StandardReport): '*/matplotlib/_mathtext_data.py', '*/matplotlib/_pylab_helpers.py', '*/matplotlib/afm.py', - '*/matplotlib/animation.py', '*/matplotlib/artist.py', '*/matplotlib/axes.py', '*/matplotlib/axis.py',