Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07adcde

Browse files
committed
Merge branch 'v2.x'
2 parents a30f451 + 1c6b59a commit 07adcde

32 files changed

+791
-876
lines changed

doc/users/whats_new.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ Support for HiDPI (Retina) displays in the NbAgg and WebAgg backends
216216
The NbAgg and WebAgg backends will now use the full resolution of your
217217
high-pixel-density display.
218218

219+
Change in the default animation codec
220+
-------------------------------------
221+
222+
The default animation codec has been changed from ``mpeg4`` to ``h264``,
223+
which is more efficient. It can be set via the ``animation.codec`` rcParam.
224+
225+
Deprecated support for mencoder in animation
226+
--------------------------------------------
227+
228+
The use of mencoder for writing video files with mpl is problematic;
229+
switching to ffmpeg is strongly advised. All support for mencoder
230+
will be removed in version 2.2.
219231

220232

221233
Previous Whats New

lib/matplotlib/afm.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
... 'fonts', 'afm', 'ptmr8a.afm')
2020
>>>
2121
>>> from matplotlib.afm import AFM
22-
>>> afm = AFM(open(afm_fname))
22+
>>> with open(afm_fname) as fh:
23+
... afm = AFM(fh)
2324
>>> afm.string_width_height('What the heck?')
2425
(6220.0, 694)
2526
>>> afm.get_fontname()

lib/matplotlib/animation.py

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import contextlib
3838
import tempfile
3939
import warnings
40-
from matplotlib.cbook import iterable, is_string_like
40+
from matplotlib.cbook import iterable, is_string_like, deprecated
4141
from matplotlib.compat import subprocess
4242
from matplotlib import verbose
4343
from matplotlib import rcParams, rcParamsDefault, rc_context
@@ -61,6 +61,12 @@
6161
# how-to-encode-series-of-images-into-h264-using-x264-api-c-c )
6262

6363

64+
def adjusted_figsize(w, h, dpi, n):
65+
wnew = int(w * dpi / n) * n / dpi
66+
hnew = int(h * dpi / n) * n / dpi
67+
return wnew, hnew
68+
69+
6470
# A registry for available MovieWriter classes
6571
class MovieWriterRegistry(object):
6672
def __init__(self):
@@ -194,10 +200,6 @@ class MovieWriter(AbstractMovieWriter):
194200
The format used in writing frame data, defaults to 'rgba'
195201
'''
196202

197-
# Specifies whether the size of all frames need to be identical
198-
# i.e. whether we can use savefig.bbox = 'tight'
199-
frame_size_can_vary = False
200-
201203
def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
202204
metadata=None):
203205
'''
@@ -249,8 +251,20 @@ def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
249251
@property
250252
def frame_size(self):
251253
'A tuple (width,height) in pixels of a movie frame.'
252-
width_inches, height_inches = self.fig.get_size_inches()
253-
return width_inches * self.dpi, height_inches * self.dpi
254+
w, h = self.fig.get_size_inches()
255+
return int(w * self.dpi), int(h * self.dpi)
256+
257+
def _adjust_frame_size(self):
258+
if self.codec == 'h264':
259+
wo, ho = self.fig.get_size_inches()
260+
w, h = adjusted_figsize(wo, ho, self.dpi, 2)
261+
if not (wo, ho) == (w, h):
262+
self.fig.set_size_inches(w, h, forward=True)
263+
verbose.report('figure size (inches) has been adjusted '
264+
'from %s x %s to %s x %s' % (wo, ho, w, h),
265+
level='helpful')
266+
verbose.report('frame size in pixels is %s x %s' % self.frame_size,
267+
level='debug')
254268

255269
def setup(self, fig, outfile, dpi):
256270
'''
@@ -267,6 +281,7 @@ def setup(self, fig, outfile, dpi):
267281
self.outfile = outfile
268282
self.fig = fig
269283
self.dpi = dpi
284+
self._adjust_frame_size()
270285

271286
# Run here so that grab_frame() can write the data to a pipe. This
272287
# eliminates the need for temp files.
@@ -364,10 +379,6 @@ def isAvailable(cls):
364379
class FileMovieWriter(MovieWriter):
365380
'`MovieWriter` subclass that handles writing to a file.'
366381

367-
# In general, if frames are writen to files on disk, it's not important
368-
# that they all be identically sized
369-
frame_size_can_vary = True
370-
371382
def __init__(self, *args, **kwargs):
372383
MovieWriter.__init__(self, *args, **kwargs)
373384
self.frame_format = rcParams['animation.frame_format']
@@ -393,6 +404,8 @@ def setup(self, fig, outfile, dpi, frame_prefix='_tmp', clear_temp=True):
393404
self.fig = fig
394405
self.outfile = outfile
395406
self.dpi = dpi
407+
self._adjust_frame_size()
408+
396409
self.clear_temp = clear_temp
397410
self.temp_prefix = frame_prefix
398411
self._frame_counter = 0 # used for generating sequential file names
@@ -448,10 +461,9 @@ def grab_frame(self, **savefig_kwargs):
448461
try:
449462
# Tell the figure to save its data to the sink, using the
450463
# frame format and dpi.
451-
myframesink = self._frame_sink()
452-
self.fig.savefig(myframesink, format=self.frame_format,
453-
dpi=self.dpi, **savefig_kwargs)
454-
myframesink.close()
464+
with self._frame_sink() as myframesink:
465+
self.fig.savefig(myframesink, format=self.frame_format,
466+
dpi=self.dpi, **savefig_kwargs)
455467

456468
except RuntimeError:
457469
out, err = self._proc.communicate()
@@ -548,7 +560,7 @@ class FFMpegFileWriter(FileMovieWriter, FFMpegBase):
548560
def _args(self):
549561
# Returns the command line parameters for subprocess to use
550562
# ffmpeg to create a movie using a collection of temp images
551-
return [self.bin_path(), '-r', str(self.fps),
563+
return [self.bin_path(), # -r option is not needed before -i option
552564
'-i', self._base_temp_name(),
553565
'-vframes', str(self._frame_counter),
554566
'-r', str(self.fps)] + self.output_args
@@ -608,9 +620,20 @@ def output_args(self):
608620
return args
609621

610622

611-
# Combine Mencoder options with pipe-based writing
623+
# The message must be a single line; internal newlines cause sphinx failure.
624+
mencoder_dep = ("Support for mencoder is only partially functional, "
625+
"and will be removed entirely in 2.2. "
626+
"Please use ffmpeg instead.")
627+
628+
612629
@writers.register('mencoder')
613630
class MencoderWriter(MovieWriter, MencoderBase):
631+
632+
@deprecated('2.0', message=mencoder_dep)
633+
def __init__(self, *args, **kwargs):
634+
with rc_context(rc={'animation.codec': 'mpeg4'}):
635+
super(MencoderWriter, self).__init__(*args, **kwargs)
636+
614637
def _args(self):
615638
# Returns the command line parameters for subprocess to use
616639
# mencoder to create a movie
@@ -625,6 +648,11 @@ def _args(self):
625648
class MencoderFileWriter(FileMovieWriter, MencoderBase):
626649
supported_formats = ['png', 'jpeg', 'tga', 'sgi']
627650

651+
@deprecated('2.0', message=mencoder_dep)
652+
def __init__(self, *args, **kwargs):
653+
with rc_context(rc={'animation.codec': 'mpeg4'}):
654+
super(MencoderFileWriter, self).__init__(*args, **kwargs)
655+
628656
def _args(self):
629657
# Returns the command line parameters for subprocess to use
630658
# mencoder to create a movie
@@ -836,7 +864,7 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
836864
elif (not is_string_like(writer) and
837865
any(arg is not None
838866
for arg in (fps, codec, bitrate, extra_args, metadata))):
839-
raise RuntimeError('Passing in values for arguments for arguments '
867+
raise RuntimeError('Passing in values for arguments '
840868
'fps, codec, bitrate, extra_args, or metadata '
841869
'is not supported when writer is an existing '
842870
'MovieWriter instance. These should instead be '
@@ -892,26 +920,16 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
892920
metadata=metadata)
893921
except IndexError:
894922
raise ValueError("Cannot save animation: no writers are "
895-
"available. Please install mencoder or "
923+
"available. Please install "
896924
"ffmpeg to save animations.")
897925

898926
verbose.report('Animation.save using %s' % type(writer),
899927
level='helpful')
900928

901-
# FIXME: Using 'bbox_inches' doesn't currently work with
902-
# writers that pipe the data to the command because this
903-
# requires a fixed frame size (see Ryan May's reply in this
904-
# thread: [1]). Thus we drop the 'bbox_inches' argument if it
905-
# exists in savefig_kwargs.
906-
#
907-
# [1] (http://matplotlib.1069221.n5.nabble.com/
908-
# Animation-class-let-save-accept-kwargs-which-
909-
# are-passed-on-to-savefig-td39627.html)
910-
#
911-
if 'bbox_inches' in savefig_kwargs and not writer.frame_size_can_vary:
929+
if 'bbox_inches' in savefig_kwargs:
912930
warnings.warn("Warning: discarding the 'bbox_inches' argument in "
913-
"'savefig_kwargs' as it not supported by "
914-
"{0}).".format(writer.__class__.__name__))
931+
"'savefig_kwargs' as it may cause frame size "
932+
"to vary, which is inappropriate for animation.")
915933
savefig_kwargs.pop('bbox_inches')
916934

917935
# Create a new sequence of frames for saved data. This is different
@@ -921,12 +939,10 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
921939
# since GUI widgets are gone. Either need to remove extra code to
922940
# allow for this non-existent use case or find a way to make it work.
923941
with rc_context():
924-
# See above about bbox_inches savefig kwarg
925-
if (not writer.frame_size_can_vary and
926-
rcParams['savefig.bbox'] == 'tight'):
927-
verbose.report("Disabling savefig.bbox = 'tight', as it is "
928-
"not supported by "
929-
"{0}.".format(writer.__class__.__name__),
942+
if (rcParams['savefig.bbox'] == 'tight'):
943+
verbose.report("Disabling savefig.bbox = 'tight', as it "
944+
"may cause frame size to vary, which "
945+
"is inappropriate for animation.",
930946
level='helpful')
931947
rcParams['savefig.bbox'] = None
932948
with writer.saving(self._fig, filename, dpi):

lib/matplotlib/artist.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,8 @@ def pickable(self):
426426
self._picker is not None)
427427

428428
def pick(self, mouseevent):
429-
"""Process pick event
430-
431-
call signature::
432-
433-
pick(mouseevent)
429+
"""
430+
Process pick event
434431
435432
each child artist will fire a pick event if *mouseevent* is over
436433
the artist and the artist has picker set

0 commit comments

Comments
 (0)