8000 Merge remote-tracking branch 'matplotlib/master' · matplotlib/matplotlib@74270f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 74270f6

Browse files
committed
Merge remote-tracking branch 'matplotlib/master'
2 parents 7b89443 + 212b0ff commit 74270f6

34 files changed

+1105
-993
lines changed

doc/devel/documenting_mpl.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,23 @@ function that takes a ``**kwargs``. The requirements are:
8686
2. as automated as possible so that as properties change, the docs
8787
are updated automagically.
8888

89-
The functions :attr:`matplotlib.artist.kwdocd` and
90-
:func:`matplotlib.artist.kwdoc` to facilitate this. They combine
89+
The function :func:`matplotlib.artist.kwdoc` and the decorator
90+
:func:`matplotlib.docstring.dedent_interpd` facilitate this. They combine
9191
python string interpolation in the docstring with the matplotlib
9292
artist introspection facility that underlies ``setp`` and ``getp``.
93-
The ``kwdocd`` is a single dictionary that maps class name to a
94-
docstring of ``kwargs``. Here is an example from
93+
The ``kwdoc`` function gives the list of properties as a docstring. In order
94+
to use this in another docstring, first update the
95+
``matplotlib.docstring.interpd`` object, as seen in this example from
9596
:mod:`matplotlib.lines`::
9697

9798
# in lines.py
98-
artist.kwdocd['Line2D'] = artist.kwdoc(Line2D)
99+
docstring.interpd.update(Line2D=artist.kwdoc(Line2D))
99100

100101
Then in any function accepting :class:`~matplotlib.lines.Line2D`
101102
pass-through ` F438 `kwargs``, e.g., :meth:`matplotlib.axes.Axes.plot`::
102103

103104
# in axes.py
105+
@docstring.dedent_interpd
104106
def plot(self, *args, **kwargs):
105107
"""
106108
Some stuff omitted
@@ -114,7 +116,6 @@ pass-through ``kwargs``, e.g., :meth:`matplotlib.axes.Axes.plot`::
114116
information
115117
"""
116118
pass
117-
plot.__doc__ = cbook.dedent(plot.__doc__) % artist.kwdocd
118119

119120
Note there is a problem for :class:`~matplotlib.artist.Artist`
120121
``__init__`` methods, e.g., :meth:`matplotlib.patches.Patch.__init__`,
@@ -123,7 +124,7 @@ work until the class is fully defined and we can't modify the
123124
``Patch.__init__.__doc__`` docstring outside the class definition.
124125
There are some some manual hacks in this case, violating the
125126
"single entry point" requirement above -- see the
126-
``artist.kwdocd['Patch']`` setting in :mod:`matplotlib.patches`.
127+
``docstring.interpd.update`` calls in :mod:`matplotlib.patches`.
127128

128129
.. _formatting-mpl-docs:
129130

doc/faq/usage_faq.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ WXAgg Agg rendering to to a :term:`wxWidgets` canvas
430430
WX Native :term:`wxWidgets` drawing to a :term:`wxWidgets` Canvas
431431
(not recommended) (requires wxPython_)
432432
TkAgg Agg rendering to a :term:`Tk` canvas (requires TkInter_)
433-
Qt4Agg Agg rendering to a :term:`Qt4` canvas (requires PyQt4_)
433+
Qt4Agg Agg rendering to a :term:`Qt4` canvas (requires PyQt4_ or ``pyside``)
434+
Qt5Agg Agg rendering in a :term:`Qt5` canvas (requires PyQt5_)
434435
macosx Cocoa rendering in OSX windows
435436
(presently lacks blocking show() behavior when matplotlib
436437
is in non-interactive mode)
@@ -448,6 +449,7 @@ macosx Cocoa rendering in OSX windows
448449
.. _wxPython: http://www.wxpython.org/
449450
.. _TkInter: http://wiki.python.org/moin/TkInter
450451
.. _PyQt4: http://www.riverbankcomputing.co.uk/software/pyqt/intro
452+
.. _PyQt5: http://www.riverbankcomputing.co.uk/software/pyqt/intro
451453

452454
How do I select PyQt4 or PySide?
453455
========================================

doc/glossary/index.rst

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ Glossary
7373
pyqt
7474
`pyqt <http://wiki.python.org/moin/PyQt>`_ provides python
7575
wrappers for the :term:`Qt` widgets library and is required by
76-
the matplotlib QtAgg and Qt4Agg backends. Widely used on linux
76+
the matplotlib Qt5Agg and Qt4Agg backends. Widely used on linux
7777
and windows; many linux distributions package this as
78-
'python-qt3' or 'python-qt4'.
78+
'python-qt5' or 'python-qt4'.
7979

8080
python
8181
`python <http://python.org>`_ is an object oriented interpreted
@@ -91,13 +91,18 @@ Glossary
9191

9292

9393
Qt
94-
`Qt <http://trolltech.com/products/qt/>`__ is a cross-platform
94+
`Qt <http://www.qt.io/>`__ is a cross-platform
9595
application framework for desktop and embedded development.
9696

9797
Qt4
98-
`Qt4 <http://trolltech.com/products/qt/>`__ is the most recent
99-
version of Qt cross-platform application framework for desktop
100-
and embedded development.
98+
`Qt4 <http://doc.qt.io/qt-4.8/index.html>`__ is the previous,
99+
but most widely used, version of Qt cross-platform application
100+
framework for desktop and embedded development.
101+
102+
Qt5
103+
`Qt5 <http://doc.qt.io/qt-5/index.html>`__ is the current
104+
version of Qt cross-platform application
105+
framework for desktop and embedded development.
101106

102107
raster graphics
103108
`Raster graphics

doc/users/whats_new/styles.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Styles
2+
------
3+
4+
Several new styles have been added, including many styles from the Seaborn project.
5+
Additionally, in order to prep for the upcoming 2.0 style-change release, a 'classic' and 'default' style has been added.
6+
For this release, the 'default' and 'classic' styles are identical.
7+
By using them now in your scripts, you can help ensure a smooth transition during future upgrades of matplotlib, so that you can upgrade to the snazzy new defaults when you are ready! ::
8+
9+
import matplotlib.style
10+
matplotlib.style.use('classic')
11+
12+
The 'default' style will give you matplotlib's latest plotting styles::
13+
14+
matplotlib.style.use('default')
15+

examples/pylab_examples/major_minor_demo1.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#!/usr/bin/env python
21
"""
32
Demonstrate how to use major and minor tickers.
43
@@ -19,7 +18,7 @@
1918
some base. The FormatStrFormatter uses a string format string (e.g.,
2019
'%d' or '%1.2f' or '%1.1f cm' ) to format the tick
2120
22-
The pylab interface grid command changes the grid settings of the
21+
The pyplot interface grid command changes the grid settings of the
2322
major ticks of the y and y axis together. If you want to control the
2423
grid of the minor ticks for a given axis, use for example
2524

examples/pylab_examples/manual_axis.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
66
This example should be considered deprecated and is left just for demo
77
purposes for folks wanting to make a pseudo-axis
8-
98
"""
109

1110
import numpy as np
12-
from pylab import figure, show
11+
import matplotlib.pyplot as plt
1312
import matplotlib.lines as lines
1413

1514

@@ -47,7 +46,7 @@ def make_yaxis(ax, xloc=0, offset=0.05, **props):
4746
props = dict(color='black', linewidth=2, markeredgewidth=2)
4847
x = np.arange(200.)
4948
y = np.sin(2*np.pi*x/200.) + np.random.rand(200) - 0.5
50-
fig = figure(facecolor='white')
49+
fig = plt.figure(facecolor='white')
5150
ax = fig.add_subplot(111, frame_on=False)
5251
ax.axison = False
5352
ax.plot(x, y, 'd', markersize=8, markerfacecolor='blue')
@@ -56,4 +55,4 @@ def make_yaxis(ax, xloc=0, offset=0.05, **props):
5655
make_xaxis(ax, 0, offset=0.1, **props)
5756
make_yaxis(ax, 0, offset=5, **props)
5857

59-
show()
58+
plt.show()
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
#!/usr/bin/env python
21
"""
32
make the matplotlib svg minimization icon
43
"""
4+
import matplotlib.pyplot as plt
55
import matplotlib
6-
#matplotlib.use('Svg')
7-
from pylab import *
6+
import numpy as np
87

9-
rc('grid', ls='-', lw=2, color='k')
10-
fig = figure(figsize=(1, 1), dpi=72)
11-
axes([0.025, 0.025, 0.95, 0.95], axisbg='#bfd1d4')
8+
matplotlib.rc('grid', ls='-', lw=2, color='k')
9+
fig = plt.figure(figsize=(1, 1), dpi=72)
10+
plt.axes([0.025, 0.025, 0.95, 0.95], axisbg='#bfd1d4')
1211

13-
t = arange(0, 2, 0.05)
14-
s = sin(2*pi*t)
15-
plot(t, s, linewidth=4, color="#ca7900")
16-
axis([-.2, 2.2, -1.2, 1.2])
12+
t = np.arange(0, 2, 0.05)
13+
s = np.sin(2*np.pi*t)
14+
plt.plot(t, s, linewidth=4, color="#ca7900")
15+
plt.axis([-.2, 2.2, -1.2, 1.2])
1716

18-
# grid(True)
19-
setp(gca(), xticklabels=[], yticklabels=[])
20-
savefig('matplotlib', facecolor='0.75')
17+
ax = plt.gca()
18+
ax.set_xticklabels([])
19+
ax.set_yticklabels([])
20+
21+
plt.show()

examples/pylab_examples/system_monitor.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ def get_net():
2121
def get_stats():
2222
return get_memory(), get_cpu(), get_net()
2323

24-
25-
# turn interactive mode on for dynamic updates. If you aren't in
26-
# interactive mode, you'll need to use a GUI event handler/timer.
27-
plt.ion()
28-
2924
fig, ax = plt.subplots()
3025
ind = np.arange(1, 4)
26+
27+
# show the figure, but do not block
28+
plt.show(block=False)
29+
30+
3131
pm, pc, pn = plt.bar(ind, get_stats())
3232
centers = ind + 0.5*pm.get_width()
3333
pm.set_facecolor('r')
@@ -44,10 +44,21 @@ def get_stats():
4444
for i in range(200): # run for a little while
4545
m, c, n = get_stats()
4646

47+
# update the animated artists
4748
pm.set_height(m)
4849
pc.set_height(c)
4950
pn.set_height(n)
51+
52+
# ask the canvas to re-draw itself the next time it
53+
# has a chance.
54+
# For most of the GUI backends this adds an event to the queue
55+
# of the GUI frameworks event loop.
56+
fig.canvas.draw_idle()
5057
try:
58+
# make sure that the GUI framework has a chance to run its event loop
59+
# and clear any GUI events. This needs to be in a try/except block
60+
# because the default implemenation of this method is to raise
61+
# NotImplementedError
5162
fig.canvas.flush_events()
5263
except NotImplementedError:
5364
pass

lib/matplotlib/animation.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,17 +1030,18 @@ def __init__(self, fig, artists, *args, **kwargs):
10301030

10311031
def _init_draw(self):
10321032
# Make all the artists involved in *any* frame invisible
1033-
axes = []
1033+
figs = set()
10341034
for f in self.new_frame_seq():
10351035
for artist in f:
10361036
artist.set_visible(False)
1037+
artist.set_animated(self._blit)
10371038
# Assemble a list of unique axes that need flushing
1038-
if artist.axes not in axes:
1039-
axes.append(artist.axes)
1039+
if artist.axes.figure not in figs:
1040+
figs.add(artist.axes.figure)
10401041

10411042
# Flush the needed axes
1042-
for ax in axes:
1043-
ax.figure.canvas.draw()
1043+
for fig in figs:
1044+
fig.canvas.draw()
10441045

10451046
def _pre_draw(self, 10000 framedata, blit):
10461047
'''
@@ -1155,6 +1156,8 @@ def _init_draw(self):
11551156
self._draw_frame(next(self.new_frame_seq()))
11561157
else:
11571158
self._drawn_artists = self._init_func()
1159+
for a in self._drawn_artists:
1160+
a.set_animated(self._blit)
11581161

11591162
def _draw_frame(self, framedata):
11601163
# Save the data for potential saving of movies.
@@ -1167,3 +1170,5 @@ def _draw_frame(self, framedata):
11671170
# Call the func with framedata and args. If blitting is desired,
11681171
# func needs to return a sequence of any artists that were modified.
11691172
self._drawn_artists = self._func(framedata, *self._args)
1173+
for a in self._drawn_artists:
1174+
a.set_animated(self._blit)

lib/matplotlib/artist.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,9 @@ def draw_wrapper(artist, renderer, *args, **kwargs):
6868
return draw_wrapper
6969

7070

71-
def _stale_figure_callback(self):
72-
self.figure.stale = True
73-
74-
75-
def _stale_axes_callback(self):
76-
self.axes.stale = True
71+
def _stale_axes_callback(self, val):
72+
if self.axes:
73+
self.axes.stale = val
7774

7875

7976
class Artist(object):
@@ -87,6 +84,7 @@ class Artist(object):
8784

8885
def __init__(self):
8986
self._stale = True
87+
self.stale_callback = None
9088
self._axes = None
9189
self.figure = None
9290

@@ -124,6 +122,7 @@ def __getstate__(self):
124122
# remove the unpicklable remove method, this will get re-added on load
125123
# (by the axes) if the artist lives on an axes.
126124
d['_remove_method'] = None
125+
d['stale_callback'] = None
127126
return d
128127

129128
def remove(self):
@@ -222,7 +221,7 @@ def axes(self, new_axes):
222221

223222
self._axes = new_axes
224223
if new_axes is not None and new_axes is not self:
225-
self.add_callback(_stale_axes_callback)
224+
self.stale_callback = _stale_axes_callback
226225

227226
return new_axes
228227

@@ -236,15 +235,16 @@ def stale(self):
236235

237236
@stale.setter
238237
def stale(self, val):
239-
# only trigger call-back stack on being marked as 'stale'
240-
# when not already stale
241-
# the draw process will take care of propagating the cleaning
242-
# process
243-
if not (self._stale == val):
244-
self._stale = val
245-
# only trigger propagation if marking as stale
246-
if self._stale:
247-
self.pchanged()
238+
self._stale = val
239+
240+
# if the artist is animated it does not take normal part in the
241+
# draw stack and is not expected to be drawn as part of the normal
242+
# draw loop (when not saving) so do not propagate this change
243+
if self.get_animated():
244+
return
245+
246+
if val and self.stale_callback is not None:
247+
self.stale_callback(self, val)
248248

249249
def get_window_extent(self, renderer):
250250
"""
@@ -608,9 +608,19 @@ def set_figure(self, fig):
608608
609609
ACCEPTS: a :class:`matplotlib.figure.Figure` instance
610610
"""
611+
# if this is a no-op just return
612+
if self.figure is fig:
613+
return
614+
# if we currently have a figure (the case of both `self.figure`
615+
# and `fig` being none is taken care of above) we then user is
616+
# trying to change the figure an artist is associated with which
617+
# is not allowed for the same reason as adding the same instance
618+
# to more than one Axes
619+
if self.figure is not None:
620+
raise RuntimeError("Can not put single artist in "
621+
"more than one figure")
611622
self.figure = fig
612623
if self.figure and self.figure is not self:
613-
self.add_callback(_stale_figure_callback)
614624
self.pchanged()
615625
self.stale = True
616626

@@ -804,9 +814,9 @@ def set_animated(self, b):
804814
805815
ACCEPTS: [True | False]
806816
"""
807-
self._animated = b
808-
self.pchanged()
809-
self.stale = True
817+
if self._animated != b:
818+
self._animated = b
819+
self.pchanged()
810820

811821
def update(self, props):
812822
"""

0 commit comments

Comments
 (0)
0