Skip to content

Commit cb5f537

Browse files
committed
Merge pull request #6374 from tacaswell/fix_cn_bugs
Fix cn bugs
2 parents a38e1da + e3165c5 commit cb5f537

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

lib/matplotlib/colors.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@
5454
"""
5555
from __future__ import (absolute_import, division, print_function,
5656
unicode_literals)
57-
57+
import re
5858
from matplotlib.externals import six
5959
from matplotlib.externals.six.moves import zip
6060
import warnings
61-
import re
61+
6262
import numpy as np
6363
from numpy import ma
6464
import matplotlib.cbook as cbook
@@ -194,14 +194,17 @@ def to_rgb(self, arg):
194194
raise ValueError(
195195
'to_rgb: arg "%s" is unhashable even inside a tuple'
196196
% (str(arg),))
197-
198197
try:
199198
if cbook.is_string_like(arg):
200199
argl = arg.lower()
201200
color = self.colors.get(argl, None)
202201
if color is None:
203202
try:
204203
argl = self._parse_nth_color(arg)
204+
# in this case we do not want to cache in case
205+
# the rcparam changes, recurse with the actual color
206+
# value
207+
return self.to_rgb(argl)
205208
except ValueError:
206209
pass
207210
for cmapping in self.CN_LOOKUPS:
@@ -215,7 +218,7 @@ def to_rgb(self, arg):
215218
if fl < 0 or fl > 1:
216219
raise ValueError(
217220
'gray (string) must be in range 0-1')
218-
color = (fl,)*3
221+
color = (fl,) * 3
219222
elif cbook.iterable(arg):
220223
if len(arg) > 4 or len(arg) < 3:
221224
raise ValueError(
@@ -228,7 +231,6 @@ def to_rgb(self, arg):
228231
else:
229232
raise ValueError(
230233
'cannot convert argument to rgb sequence')
231-
232234
self.cache[arg] = color
233235

234236
except (KeyError, ValueError, TypeError) as exc:

lib/matplotlib/rcsetup.py

+27-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import operator
2323
import os
2424
import warnings
25+
import re
26+
2527
try:
2628
import collections.abc as abc
2729
except ImportError:
@@ -30,10 +32,11 @@
3032
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
3133
from matplotlib.colors import is_color_like
3234

35+
3336
# Don't let the original cycler collide with our validating cycler
3437
from cycler import Cycler, cycler as ccycler
3538

36-
#interactive_bk = ['gtk', 'gtkagg', 'gtkcairo', 'qt4agg',
39+
# interactive_bk = ['gtk', 'gtkagg', 'gtkcairo', 'qt4agg',
3740
# 'tkagg', 'wx', 'wxagg', 'cocoaagg', 'webagg']
3841
# The capitalized forms are needed for ipython at present; this may
3942
# change for later versions.
@@ -175,6 +178,7 @@ def validate_string_or_None(s):
175178
except ValueError:
176179
raise ValueError('Could not convert "%s" to string' % s)
177180

181+
178182
def validate_axisbelow(s):
179183
try:
180184
return validate_bool(s)
@@ -340,6 +344,22 @@ def validate_color_or_auto(s):
340344
return validate_color(s)
341345

342346

347+
def validate_color_for_prop_cycle(s):
348+
# Special-case the N-th color cycle syntax, this obviously can not
349+
# go in the color cycle.
350+
if isinstance(s, bytes):
351+
match = re.match(b'^C[0-9]$', s)
352+
if match is not None:
353+
raise ValueError('Can not put cycle reference ({cn!r}) in '
354+
'prop_cycler'.format(cn=s))
355+
elif isinstance(s, six.text_type):
356+
match = re.match('^C[0-9]$', s)
357+
if match is not None:
358+
raise ValueError('Can not put cycle reference ({cn!r}) in '
359+
'prop_cycler'.format(cn=s))
360+
return validate_color(s)
361+
362+
343363
def validate_color(s):
344364
'return a valid color arg'
345365
try:
@@ -649,7 +669,7 @@ def validate_hatch(s):
649669
characters: ``\\ / | - + * . x o O``.
650670
651671
"""
652-
if not isinstance(s, six.text_type):
672+
if not isinstance(s, six.string_types):
653673
raise ValueError("Hatch pattern must be a string")
654674
unique_chars = set(s)
655675
unknown = (unique_chars -
@@ -661,7 +681,8 @@ def validate_hatch(s):
661681

662682

663683
_prop_validators = {
664-
'color': validate_colorlist,
684+
'color': _listify_validator(validate_color_for_prop_cycle,
685+
allow_stringlist=True),
665686
'linewidth': validate_floatlist,
666687
'linestyle': validate_stringlist,
667688
'facecolor': validate_colorlist,
@@ -818,6 +839,9 @@ def validate_cycler(s):
818839
norm_prop = _prop_aliases.get(prop, prop)
819840
cycler_inst.change_key(prop, norm_prop)
820841

842+
for key, vals in cycler_inst.by_key().items():
843+
_prop_validators[key](vals)
844+
821845
return cycler_inst
822846

823847

lib/matplotlib/tests/test_colors.py

+19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
1818
from nose.plugins.skip import SkipTest
1919

20+
from cycler import cycler
21+
import matplotlib
2022
import matplotlib.colors as mcolors
2123
import matplotlib.cm as cm
2224
import matplotlib.cbook as cbook
@@ -596,6 +598,23 @@ def test_pandas_iterable():
596598
assert_sequence_equal(cm1.colors, cm2.colors)
597599

598600

601+
@cleanup
602+
def test_cn():
603+
matplotlib.rcParams['axes.prop_cycle'] = cycler('color',
604+
['blue', 'r'])
605+
x11_blue = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C0'))
606+
assert x11_blue == '#0000ff'
607+
red = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C1'))
608+
assert red == '#ff0000'
609+
610+
matplotlib.rcParams['axes.prop_cycle'] = cycler('color',
611+
['XKCDblue', 'r'])
612+
XKCD_blue = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C0'))
613+
assert XKCD_blue == '#0343df'
614+
red = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C1'))
615+
assert red == '#ff0000'
616+
617+
599618
if __name__ == '__main__':
600619
import nose
601620
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

lib/matplotlib/tests/test_cycles.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def test_property_collision_plot():
129129
fig, ax = plt.subplots()
130130
ax.set_prop_cycle('linewidth', [2, 4])
131131
for c in range(1, 4):
132-
ax.plot(np.arange(10), c * np.arange(10), lw=0.1)
132+
ax.plot(np.arange(10), c * np.arange(10), lw=0.1, color='k')
133133
ax.plot(np.arange(10), 4 * np.arange(10))
134134
ax.plot(np.arange(10), 5 * np.arange(10))
135135

lib/matplotlib/tests/test_rcparams.py

+1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ def test_validators():
348348
('cycler(c=[1, 2, 3])', ValueError), # invalid values
349349
("cycler(lw=['a', 'b', 'c'])", ValueError), # invalid values
350350
(cycler('waka', [1, 3, 5]), ValueError), # not a property
351+
(cycler('color', ['C1', 'r', 'g']), ValueError) # no CN
351352
)
352353
},
353354
{'validator': validate_hatch,

0 commit comments

Comments
 (0)