diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index ee536e0d7e4d..7833e19a48e2 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5,6 +5,7 @@ from matplotlib.externals.six.moves import reduce, xrange, zip, zip_longest import math +import itertools import warnings import numpy as np @@ -2446,7 +2447,7 @@ def pie(self, x, explode=None, labels=None, colors=None, Call signature:: pie(x, explode=None, labels=None, - colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'), + colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, @@ -2554,9 +2555,20 @@ def pie(self, x, explode=None, labels=None, colors=None, raise ValueError("'label' must be of length 'x'") if len(x) != len(explode): raise ValueError("'explode' must be of length 'x'") - if colors is None: + if ((colors is None) and + ('color' in self._get_patches_for_fill._prop_keys)): + def get_next_color(): + return six.next( + self._get_patches_for_fill.prop_cycler)['color'] + elif colors is None: colors = ('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w') + if colors is not None: + color_cycler = itertools.cycle(colors) + + def get_next_color(): + return six.next(color_cycler) + if radius is None: radius = 1 @@ -2591,7 +2603,7 @@ def pie(self, x, explode=None, labels=None, colors=None, w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2), 360. * max(theta1, theta2), - facecolor=colors[i % len(colors)], + facecolor=get_next_color(), **wedgeprops) slices.append(w) self.add_patch(w) @@ -2859,6 +2871,10 @@ def xywhere(xs, ys, mask): ys = [thisy for thisy, b in zip(ys, mask) if b] return xs, ys + # Set an explicit color so the color cycle doesn't advance. It + # will be set to the correct color where `ecolor` is handled + # below. + kwargs['color'] = 'k' plot_kw = {'label': '_nolegend_'} if capsize is None: capsize = rcParams["errorbar.capsize"] @@ -2873,7 +2889,8 @@ def xywhere(xs, ys, mask): plot_kw['markeredgewidth'] = capthick # For backwards-compat, allow explicit setting of # 'mew' or 'markeredgewidth' to over-ride capthick. - for key in ('markeredgewidth', 'mew', 'transform', 'alpha', 'zorder'): + for key in ('markeredgewidth', 'mew', 'transform', 'alpha', 'zorder', + 'color'): if key in kwargs: plot_kw[key] = kwargs[key] @@ -3010,16 +3027,15 @@ def xywhere(xs, ys, mask): if not barsabove and plot_line: l0, = self.plot(x, y, fmt, label='_nolegend_', **kwargs) - if ecolor is None: - if l0 is None and 'color' in self._get_lines._prop_keys: - ecolor = six.next(self._get_lines.prop_cycler)['color'] - else: - ecolor = l0.get_color() + if 'color' in self._get_lines._prop_keys: + ecolor = six.next(self._get_lines.prop_cycler)['color'] for l in barcols: l.set_color(ecolor) for l in caplines: l.set_color(ecolor) + if l0 is not None: + l0.set_color(ecolor) self.autoscale_view() self._hold = holdstate diff --git a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle index 968d993ae843..f6ba99c38fb4 100644 --- a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle @@ -495,3 +495,5 @@ animation.convert_path: convert # Path to ImageMagick's convert binary. # is also the name of a system tool. animation.convert_args: animation.html: none + +_internal.classic_mode: True \ No newline at end of file diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 97d0015a4ec6..ab4e3e3c9a47 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -965,14 +965,18 @@ def validate_cycler(s): # This entry can be either a cycler object or a # string repr of a cycler-object, which gets eval()'ed # to create the object. - 'axes.prop_cycle': [ccycler('color', 'bgrcmyk'), - validate_cycler], - 'axes.xmargin': [0, ValidateInterval(0, 1, - closedmin=True, - closedmax=True)], # margin added to xaxis - 'axes.ymargin': [0, ValidateInterval(0, 1, - closedmin=True, - closedmax=True)],# margin added to yaxis + 'axes.prop_cycle': [ + ccycler('color', + ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', + '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', + '#bcbd22', '#17becf']), + validate_cycler], + 'axes.xmargin': [0.05, ValidateInterval(0, 1, + closedmin=True, + closedmax=True)], # margin added to xaxis + 'axes.ymargin': [0.05, ValidateInterval(0, 1, + closedmin=True, + closedmax=True)],# margin added to yaxis 'polaraxes.grid': [True, validate_bool], # display polar grid or # not @@ -1191,7 +1195,14 @@ def validate_cycler(s): 'animation.convert_path': ['convert', six.text_type], # Additional arguments for mencoder movie writer (using pipes) - 'animation.convert_args': [[], validate_stringlist]} + 'animation.convert_args': [[], validate_stringlist], + + # Classic (pre 2.0) compatibility mode + # This is used for things that are hard to make backward compatible + # with a sane rcParam alone. This does *not* turn on classic mode + # altogether. For that use `matplotlib.style.use('classic')`. + '_internal.classic_mode': [False, validate_bool] +} if __name__ == '__main__': diff --git a/lib/matplotlib/sankey.py b/lib/matplotlib/sankey.py index 423884723461..2fff5b93790c 100755 --- a/lib/matplotlib/sankey.py +++ b/lib/matplotlib/sankey.py @@ -45,6 +45,7 @@ from matplotlib.transforms import Affine2D from matplotlib import verbose from matplotlib import docstring +from matplotlib import rcParams __author__ = "Kevin L. Davies" __credits__ = ["Yannick Copin"] @@ -444,8 +445,6 @@ def add(self, patchlabel='', flows=None, orientations=None, labels='', %(Patch)s As examples, ``fill=False`` and ``label='A legend entry'``. - By default, ``facecolor='#bfd1d4'`` (light blue) and - ``linewidth=0.5``. The indexing parameters (*prior* and *connect*) are zero-based. @@ -770,11 +769,15 @@ def _get_angle(a, r): print("lrpath\n", self._revert(lrpath)) xs, ys = list(zip(*vertices)) self.ax.plot(xs, ys, 'go-') - patch = PathPatch(Path(vertices, codes), - fc=kwargs.pop('fc', kwargs.pop('facecolor', - '#bfd1d4')), # Custom defaults - lw=kwargs.pop('lw', kwargs.pop('linewidth', 0.5)), - **kwargs) + if rcParams['_internal.classic_mode']: + fc = kwargs.pop('fc', kwargs.pop('facecolor', '#bfd1d4')) + lw = kwargs.pop('lw', kwargs.pop('linewidth', 0.5)) + else: + fc = kwargs.pop('fc', kwargs.pop('facecolor', None)) + lw = kwargs.pop('lw', kwargs.pop('linewidth', None)) + if fc is None: + fc = six.next(self.ax._get_patches_for_fill.prop_cycler)['color'] + patch = PathPatch(Path(vertices, codes), fc=fc, lw=lw, **kwargs) self.ax.add_patch(patch) # Add the path labels. diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.pdf b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.pdf index 30036fa5f637..7114e3969579 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.pdf and b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.png b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.png index 71c2a1cecbb0..6c65dfc16192 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.png and b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.svg b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.svg index 175eeb9bd42f..2fa3c44fa312 100644 --- a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.svg +++ b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_limits.svg @@ -5,1122 +5,1110 @@ - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - + + + - - - + + + - - - - + + + + - - - + + + - - - + + + - - - - - - - - + + + + + + + + - + - + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - + - - - - + + + + - - - - + + + + - + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - + - - - - + + + + - - - - + + + + - + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - + + + + + - - - - - + + + + + - + - - - - + + + + - - - - + + + + - + - - - - + + + + - - - - + + + + - + - +" id="m643ad1d0f3" style="stroke:#000000;stroke-width:0.5;"/> - - - - - - - - - - - + + + + + + + + + + + - + - - - - + + + + - + - - - - + + + + - + - - + + - + - - + + - +" id="m6d0f9d3244" style="stroke:#0000ff;stroke-width:0.5;"/> - - - - - - - - - - - + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - +" id="DejaVuSans-31"/> - + - + - + - + - + - + - + - + - + - + - + - +" id="DejaVuSans-34"/> - + - + - + - +" id="DejaVuSans-35"/> - + @@ -1129,187 +1117,185 @@ z - + - + - + - + - - + +" id="DejaVuSans-2212"/> - - - - + + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + @@ -1317,378 +1303,370 @@ z - - - - - - - + + - + + + - + + + - + - - + + + - - + + - - - + +" id="DejaVuSans-6c"/> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf index cff1fc76d70c..7ccd59264f48 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf and b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.pdf b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.pdf index 7b488be16e95..1bab8ea4976b 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.pdf and b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.png b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.png index b4c010f68eeb..4f34e2a0e439 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.png and b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.svg b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.svg index 358cdf9937cb..aa413ad5ef67 100644 --- a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.svg +++ b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_zorder.svg @@ -5,530 +5,513 @@ - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +" id="DejaVuSans-31"/> - + - + - + - + - + - + - + - + - + - + - + - +" id="DejaVuSans-34"/> - + - + - + - +" id="DejaVuSans-35"/> - + - + - + - + - + - + - + - +" id="DejaVuSans-37"/> - + - + - + - + - + - + - + - + - + @@ -537,516 +520,495 @@ Q23.9688 32.4219 30.6094 32.4219" id="BitstreamVeraSans-Roman-39"/> - + - + - + - + - +" id="DejaVuSans-2212"/> - - - + + + - + - + - - + + - + - + - + - + - + - + - + - + - - + + - + - + - - - - + + - + - - + + - + + - - + + +" id="DejaVuSans-72"/> - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - + + + + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/lib/matplotlib/tests/baseline_images/test_colors/color_cycle.png b/lib/matplotlib/tests/baseline_images/test_colors/color_cycle.png new file mode 100644 index 000000000000..d97f1b41dcf6 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_colors/color_cycle.png differ diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index c9166a5a7db3..989b943c45d8 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -14,6 +14,7 @@ import matplotlib.cm as cm import matplotlib.cbook as cbook import matplotlib.pyplot as plt +from matplotlib.sankey import Sankey from matplotlib.testing.decorators import (image_comparison, cleanup, knownfailureif) @@ -536,6 +537,53 @@ def _azimuth2math(azimuth, elevation): return theta, phi +@image_comparison(baseline_images=["color_cycle"], extensions=['png'], + style='default') +def test_color_cycle(): + # Test that various plot types are using the color cycle + + fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2) + + ax1.pie([1, 2, 3, 4]) + + sankey = Sankey(ax=ax2, scale=0.01, offset=0.2, head_angle=180, + format='%.0f', unit='%') + sankey.add(flows=[25, 0, 60, -10, -20, -5, -15, -10, -40], + labels=['', '', '', 'First', 'Second', 'Third', 'Fourth', + 'Fifth', 'Hurray!'], + orientations=[-1, 1, 0, 1, 1, 1, -1, -1, 0], + pathlengths=[0.25, 0.25, 0.25, 0.25, 0.25, 0.6, 0.25, 0.25, + 0.25], + patchlabel="Widget\nA") + diagrams = sankey.finish() + + x = np.arange(0.5, 5.5, 0.5) + y = np.exp(-x) + xerr = 0.1 + yerr = 0.2 + + # standard error bars + ax3.errorbar(x, y, xerr=xerr, yerr=yerr) + + # including upper limits + uplims = np.zeros(x.shape) + uplims[[1, 5, 9]] = True + ax3.errorbar(x, y + 0.5, xerr=xerr, yerr=yerr, uplims=uplims) + + # including lower limits + lolims = np.zeros(x.shape) + lolims[[2, 4, 8]] = True + ax3.errorbar(x, y + 1.0, xerr=xerr, yerr=yerr, lolims=lolims) + + # including upper and lower limits + ax3.errorbar(x, y + 1.5, marker='o', ms=8, xerr=xerr, yerr=yerr, + lolims=lolims, uplims=uplims) + + ax4.plot([1, 2, 3]) + ax4.plot([4, 5, 6]) + ax4.plot([7, 8, 9]) + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/matplotlibrc.template b/matplotlibrc.template index 16c78d43967d..fd1127399730 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -312,7 +312,10 @@ backend : %(backend)s #axes.unicode_minus : True # use unicode for the minus symbol # rather than hyphen. See # http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes -#axes.prop_cycle : cycler('color', 'bgrcmyk') +#axes.prop_cycle : cycler('color', +# ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', + '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', + '#bcbd22', '#17becf']) # color cycle for plot lines # as list of string colorspecs: # single letter, long name, or