8000 Merge branch 'v1.4.x' into master · matplotlib/matplotlib@44e4427 · GitHub
[go: up one dir, main page]

Skip to content

Commit 44e4427

Browse files
committed
Merge branch 'v1.4.x' into master
2 parents 8301087 + 326b8d4 commit 44e4427

File tree

16 files changed

+128
-16
lines changed

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
pyplot_api.rst
4646
sankey_api.rst
4747
spines_api.rst
48+
style_api.rst
4849
text_api.rst
4950
ticker_api.rst
5051
tight_layout_api.rst

doc/api/style_api.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
*****
2+
style
3+
*****
4+
5+
6+
:mod:`matplotlib.style`
7+
=======================
8+
9+
.. automodule:: matplotlib.style
10+
:members:
11+
:undoc-members:
12+
:show-inheritance:
13+
:imported-members:
14+
15+
.. data:: matplotlib.style.library
16+
17+
Dictionary of available styles
18+
19+
.. data:: matplotlib.style.available
20+
21+
List of available styles

lib/matplotlib/axes/_axes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3187,7 +3187,7 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
31873187
- ``fliers``: Data beyond the whiskers (sequence of floats).
31883188
Needed if ``showfliers=True``.
31893189
3190-
- ``cilo`` & ``ciho``: Lower and upper confidence intervals
3190+
- ``cilo`` & ``cihi``: Lower and upper confidence intervals
31913191
about the median. Needed if ``shownotches=True``.
31923192
31933193
- ``label``: Name of the dataset (string). If available,

lib/matplotlib/axes/_base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,9 @@ def _xy_from_xy(self, x, y):
232232

233233
def _makeline(self, x, y, kw, kwargs):
234234
kw = kw.copy() # Don't modify the original kw.
235-
if 'color' not in kw and 'color' not in kwargs:
236-
kw['color'] = six.next(self.color_cycle)
235+
kwargs = kwargs.copy()
236+
if kw.get('color', None) is None and kwargs.get('color', None) is None:
237+
kwargs['color'] = kw['color'] = six.next(self.color_cycle)
237238
# (can't use setdefault because it always evaluates
238239
# its second argument)
239240
seg = mlines.Line2D(x, y,

lib/matplotlib/cbook.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,7 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None):
18951895
q1 first quartile (25th percentile)
18961896
q3 third quartile (75th percentile)
18971897
cilo lower notch around the median
1898-
ciho upper notch around the median
1898+
cihi upper notch around the median
18991899
whislo end of the lower whisker
19001900
whishi end of the upper whisker
19011901
fliers outliers
@@ -1977,7 +1977,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
19771977
stats['q1'] = np.nan
19781978
stats['q3'] = np.nan
19791979
stats['cilo'] = np.nan
1980-
stats['ciho'] = np.nan
1980+
stats['cihi'] = np.nan
19811981
stats['whislo'] = np.nan
19821982
stats['whishi'] = np.nan
19831983
stats['med'] = np.nan

lib/matplotlib/collections.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import matplotlib.mlab as mlab
3131

3232

33+
CIRCLE_AREA_FACTOR = 1.0 / np.sqrt(np.pi)
34+
35+
3336
class Collection(artist.Artist, cm.ScalarMappable):
3437
"""
3538
Base class for Collections. Must be subclassed to be usable.
@@ -271,25 +274,41 @@ def draw(self, renderer):
271274
from matplotlib.patheffects import PathEffectRenderer
272275
renderer = PathEffectRenderer(self.get_path_effects(), renderer)
273276

277+
# If the collection is made up of a single shape/color/stroke,
278+
# it can be rendered once and blitted multiple times, using
279+
# `draw_markers` rather than `draw_path_collection`. This is
280+
# *much* faster for Agg, and results in smaller file sizes in
281+
# PDF/SVG/PS.
282+
274283
trans = self.get_transforms()
275284
facecolors = self.get_facecolor()
276285
edgecolors = self.get_edgecolor()
286+
do_single_path_optimization = False
277287
if (len(paths) == 1 and len(trans) <= 1 and
278288
len(facecolors) == 1 and len(edgecolors) == 1 and
279289
len(self._linewidths) == 1 and
280290
self._linestyles == [(None, None)] and
281291
len(self._antialiaseds) == 1 and len(self._urls) == 1 and
282292
self.get_hatch() is None):
293+
if len(trans):
294+
combined_transform = (transforms.Affine2D(trans[0]) +
295+
transform)
296+
else:
297+
combined_transform = transform
298+
extents = paths[0].get_extents(combined_transform)
299+
width, height = renderer.get_canvas_width_height()
300+
if (extents.width < width and
301+
extents.height < height):
302+
do_single_path_optimization = True
303+
304+
if do_single_path_optimization:
283305
gc.set_foreground(tuple(edgecolors[0]))
284306
gc.set_linewidth(self._linewidths[0])
285307
gc.set_linestyle(self._linestyles[0])
286308
gc.set_antialiased(self._antialiaseds[0])
287309
gc.set_url(self._urls[0])
288-
if len(trans):
289-
transform = (transforms.Affine2D(trans[0]) +
290-
transform)
291310
renderer.draw_markers(
292-
gc, paths[0], transform.frozen(),
311+
gc, paths[0], combined_transform.frozen(),
293312
mpath.Path(offsets), transOffset, tuple(facecolors[0]))
294313
else:
295314
renderer.draw_path_collection(
@@ -713,6 +732,8 @@ class _CollectionWithSizes(Collection):
713732
"""
714733
Base class for collections that have an array of sizes.
715734
"""
735+
_factor = 1.0
736+
716737
def get_sizes(self):
717738
"""
718739
Returns the sizes of the elements in the collection. The
@@ -744,7 +765,7 @@ def set_sizes(self, sizes, dpi=72.0):
744765
else:
745766
self._sizes = np.asarray(sizes)
746767
self._transforms = np.zeros((len(self._sizes), 3, 3))
747-
scale = np.sqrt(self._sizes) * dpi / 72.0
768+
scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
748769
self._transforms[:, 0, 0] = scale
749770
self._transforms[:, 1, 1] = scale
750771
self._transforms[:, 2, 2] = 1.0
@@ -882,6 +903,8 @@ class RegularPolyCollection(_CollectionWithSizes):
882903
"""Draw a collection of regular polygons with *numsides*."""
883904
_path_generator = mpath.Path.unit_regular_polygon
884905

906+
_factor = CIRCLE_AREA_FACTOR
907+
885908
@docstring.dedent_interpd
886909
def __init__(self,
887910
numsides,
@@ -1389,6 +1412,8 @@ class CircleCollection(_CollectionWithSizes):
13891412
"""
13901413
A collection of circles, drawn using splines.
13911414
"""
1415+
_factor = CIRCLE_AREA_FACTOR
1416+
13921417
@docstring.dedent_interpd
13931418
def __init__(self, sizes, **kwargs):
13941419
"""

lib/matplotlib/figure.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ def _set_artist_props(self, a):
12461246
@docstring.dedent_interpd
12471247
def gca(self, **kwargs):
12481248
"""
1249-
Return the current axes, creating one if necessary
1249+
Get the current axes, creating one if necessary
12501250
12511251
The following kwargs are supported for ensuring the returned axes
12521252
adheres to the given projection etc., and for axes creation if
@@ -1630,6 +1630,9 @@ def get_tightbbox(self, renderer):
16301630
if ax.get_visible():
16311631
bb.append(ax.get_tightbbox(renderer))
16321632

1633+
if len(bb) == 0:
1634+
return self.bbox_inches
1635+
16331636
_bbox = Bbox.union([b for b in bb if b.width != 0 or b.height != 0])
16341637

16351638
bbox_inches = TransformedBbox(_bbox,

lib/matplotlib/font_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
""
144144
]
145145

146-
if not USE_FONTCONFIG:
146+
if not USE_FONTCONFIG and sys.platform != 'win32':
147147
home = os.environ.get('HOME')
148148
if home is not None:
149149
# user fonts on OSX

lib/matplotlib/lines.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ def set_markevery(self, every):
463463
464464
e.g., if `every=5`, every 5-th marker will be plotted.
465465
466+
ACCEPTS: [None | int | length-2 tuple of int | slice |
467+
list/array of int | float | length-2 tuple of float]
468+
466469
Parameters
467470
----------
468471
every: None | int | length-2 tuple of int | slice | list/array of int |
@@ -973,6 +976,8 @@ def set_marker(self, marker):
973976
"""
974977
Set the line marker
975978
979+
ACCEPTS: :mod:`A valid marker style <matplotlib.markers>`
980+
976981
Parameters
977982
-----------
978983

lib/matplotlib/patches.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,6 @@ def transmute(self, x0, y0, width, height, mutation_size):
23042304
codes = ([Path.MOVETO] +
23052305
[Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1) // 2) +
23062306
[Path.CLOSEPOLY])
2307-
print(len(codes), saw_vertices.shape)
23082307
return Path(saw_vertices, codes)
23092308

23102309
_style_list["roundtooth"] = Roundtooth

lib/matplotlib/pyplot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def make_active(event):
452452

453453

454454
def gcf():
455-
"Return a reference to the current figure."
455+
"Get a reference to the current figure."
456456

457457
figManager = _pylab_helpers.Gcf.get_active()
458458
if figManager is not None:
@@ -808,12 +808,12 @@ def sca(ax):
808808

809809
def gca(**kwargs):
810810
"""
811-
Return the current :class:`~matplotlib.axes.Axes` instance on the
811+
Get the current :class:`~matplotlib.axes.Axes` instance on the
812812
current figure matching the given keyword args, or create one.
813813
814814
Examples
815815
---------
816-
To get the the current polar axes on the current figure::
816+
To get the current polar axes on the current figure::
817817
818818
plt.gca(projection='polar')
819819
Loading
Loading

lib/matplotlib/tests/test_agg.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
import io
77
import os
88

9+
import numpy as np
910
from numpy.testing import assert_array_almost_equal
1011

1112
from matplotlib.image import imread
1213
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
1314
from matplotlib.figure import Figure
1415
from matplotlib.testing.decorators import cleanup
16+
from matplotlib import pyplot as plt
17+
from matplotlib import collections
18+
from matplotlib import path
1519

1620

1721
@cleanup
@@ -47,6 +51,21 @@ def test_repeated_save_with_alpha():
4751
decimal=3)
4852

4953

54+
@cleanup
55+
def test_large_single_path_collection():
56+
buff = io.BytesIO()
57+
58+
# Generates a too-large single path in a path collection that
59+
# would cause a segfault if the draw_markers optimization is
60+
# applied.
61+
f, ax = plt.subplots()
62+
collection = collections.PathCollection(
63+
[path.Path([[-10, 5], [10, 5], [10, -5], [-10, -5], [-10, 5]])])
64+
ax.add_artist(collection)
65+
ax.set_xlim(10**-3, 1)
66+
plt.savefig(buff)
67+
68+
5069
def report_memory(i):
5170
pid = os.getpid()
5271
a2 = os.popen('ps -p %d -o rss,sz' % pid).readlines()

lib/matplotlib/tests/test_axes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3466,6 +3466,12 @@ def test_pathological_hexbin():
34663466
fig.savefig(out)
34673467
assert_equal(len(w), 0)
34683468

3469+
@cleanup
3470+
def test_color_None():
3471+
# issue 3855
3472+
fig, ax = plt.subplots()
3473+
ax.plot([1,2], [1,2], color=None)
3474+
plt.show()
34693475

34703476
if __name__ == '__main__':
34713477
import nose

lib/matplotlib/tests/test_collections.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,38 @@ def test_regularpolycollection_rotate():
527527
ax.autoscale_view()
528528

529529

530+
@image_comparison(baseline_images=['regularpolycollection_scale'],
531+
extensions=['png'], remove_text=True)
532+
def test_regularpolycollection_scale():
533+
# See issue #3860
534+
535+
class SquareCollection(mcollections.RegularPolyCollection):
536+
def __init__(self, **kwargs):
537+
super(SquareCollection, self).__init__(
538+
4, rotation=np.pi/4., **kwargs)
539+
540+
def get_transform(self):
541+
"""Return transform scaling circle areas to data space."""
542+
ax = self.axes
543+
544+
pts2pixels = 72.0 / ax.figure.dpi
545+
546+
scale_x = pts2pixels * ax.bbox.width / ax.viewLim.width
547+
scale_y = pts2pixels * ax.bbox.height / ax.viewLim.height
548+
return mtransforms.Affine2D().scale(scale_x, scale_y)
549+
550+
fig, ax = plt.subplots()
551+
552+
xy = [(0, 0)]
553+
# Unit square has a half-diagonal of `1 / sqrt(2)`, so `pi * r**2`
554+
# equals...
555+
circle_areas = [np.pi / 2]
556+
squares = SquareCollection(sizes=circle_areas, offsets=xy,
557+
transOffset=ax.transData)
558+
ax.add_collection(squares, autolim=True)
559+
ax.axis([-1, 1, -1, 1])
560+
561+
530562
if __name__ == '__main__':
531563
import nose
532564
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)
0