Skip to content

Fix cn bugs #6374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)

import re
from matplotlib.externals import six
from matplotlib.externals.six.moves import zip
import warnings
import re

import numpy as np
from numpy import ma
import matplotlib.cbook as cbook
Expand Down Expand Up @@ -194,14 +194,17 @@ def to_rgb(self, arg):
raise ValueError(
'to_rgb: arg "%s" is unhashable even inside a tuple'
% (str(arg),))

try:
if cbook.is_string_like(arg):
argl = arg.lower()
color = self.colors.get(argl, None)
if color is None:
try:
argl = self._parse_nth_color(arg)
# in this case we do not want to cache in case
# the rcparam changes, recurse with the actual color
# value
return self.to_rgb(argl)
except ValueError:
pass
for cmapping in self.CN_LOOKUPS:
Expand All @@ -215,7 +218,7 @@ def to_rgb(self, arg):
if fl < 0 or fl > 1:
raise ValueError(
'gray (string) must be in range 0-1')
color = (fl,)*3
color = (fl,) * 3
elif cbook.iterable(arg):
if len(arg) > 4 or len(arg) < 3:
raise ValueError(
Expand All @@ -228,7 +231,6 @@ def to_rgb(self, arg):
else:
raise ValueError(
'cannot convert argument to rgb sequence')

self.cache[arg] = color

except (KeyError, ValueError, TypeError) as exc:
Expand Down
30 changes: 27 additions & 3 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import operator
import os
import warnings
import re

try:
import collections.abc as abc
except ImportError:
Expand All @@ -30,10 +32,11 @@
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
from matplotlib.colors import is_color_like


# Don't let the original cycler collide with our validating cycler
from cycler import Cycler, cycler as ccycler

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


def validate_axisbelow(s):
try:
return validate_bool(s)
Expand Down Expand Up @@ -340,6 +344,22 @@ def validate_color_or_auto(s):
return validate_color(s)


def validate_color_for_prop_cycle(s):
# Special-case the N-th color cycle syntax, this obviously can not
# go in the color cycle.
if isinstance(s, bytes):
match = re.match(b'^C[0-9]$', s)
if match is not None:
raise ValueError('Can not put cycle reference ({cn!r}) in '
'prop_cycler'.format(cn=s))
elif isinstance(s, six.text_type):
match = re.match('^C[0-9]$', s)
if match is not None:
raise ValueError('Can not put cycle reference ({cn!r}) in '
'prop_cycler'.format(cn=s))
return validate_color(s)


def validate_color(s):
'return a valid color arg'
try:
Expand Down Expand Up @@ -649,7 +669,7 @@ def validate_hatch(s):
characters: ``\\ / | - + * . x o O``.

"""
if not isinstance(s, six.text_type):
if not isinstance(s, six.string_types):
raise ValueError("Hatch pattern must be a string")
unique_chars = set(s)
unknown = (unique_chars -
Expand All @@ -661,7 +681,8 @@ def validate_hatch(s):


_prop_validators = {
'color': validate_colorlist,
'color': _listify_validator(validate_color_for_prop_cycle,
allow_stringlist=True),
'linewidth': validate_floatlist,
'linestyle': validate_stringlist,
'facecolor': validate_colorlist,
Expand Down Expand Up @@ -818,6 +839,9 @@ def validate_cycler(s):
norm_prop = _prop_aliases.get(prop, prop)
cycler_inst.change_key(prop, norm_prop)

for key, vals in cycler_inst.by_key().items():
_prop_validators[key](vals)

return cycler_inst


Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
from nose.plugins.skip import SkipTest

from cycler import cycler
import matplotlib
import matplotlib.colors as mcolors
import matplotlib.cm as cm
import matplotlib.cbook as cbook
Expand Down Expand Up @@ -596,6 +598,23 @@ def test_pandas_iterable():
assert_sequence_equal(cm1.colors, cm2.colors)


@cleanup
def test_cn():
matplotlib.rcParams['axes.prop_cycle'] = cycler('color',
['blue', 'r'])
x11_blue = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C0'))
assert x11_blue == '#0000ff'
red = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C1'))
assert red == '#ff0000'

matplotlib.rcParams['axes.prop_cycle'] = cycler('color',
['XKCDblue', 'r'])
XKCD_blue = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C0'))
assert XKCD_blue == '#0343df'
red = mcolors.rgb2hex(mcolors.colorConverter.to_rgb('C1'))
assert red == '#ff0000'


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
2 changes: 1 addition & 1 deletion lib/matplotlib/tests/test_cycles.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def test_property_collision_plot():
fig, ax = plt.subplots()
ax.set_prop_cycle('linewidth', [2, 4])
for c in range(1, 4):
ax.plot(np.arange(10), c * np.arange(10), lw=0.1)
ax.plot(np.arange(10), c * np.arange(10), lw=0.1, color='k')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This masks the problem exposed by the implicit inclusion of "color" into the property cycle.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means the test will pass independent of the decision on the other issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unit test is explicitly testing that the property cycler does not advance if the user specifies the property provided by the cycler. That was the original intent. The fact that it came about because of a slightly different bug doesn't matter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still tests that, just have to include all of the keys in the cycler
and as implemented on v2.x and master, 'color' is always in the cycler

On Fri, May 6, 2016, 16:40 Benjamin Root notifications@github.com wrote:

In lib/matplotlib/tests/test_cycles.py
#6374 (comment):

@@ -129,7 +129,7 @@ def test_property_collision_plot():
fig, ax = plt.subplots()
ax.set_prop_cycle('linewidth', [2, 4])
for c in range(1, 4):

  •    ax.plot(np.arange(10), c \* np.arange(10), lw=0.1)
    
  •    ax.plot(np.arange(10), c \* np.arange(10), lw=0.1, color='k')
    

This unit test is explicitly testing that the property cycler does not
advance if the user specifies the property provided by the cycler. That was
the original intent. The fact that it came about because of a slightly
different bug doesn't matter.


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
https://github.com/matplotlib/matplotlib/pull/6374/files/faae5069bb987fd5447652860a8d1fb602c3289d#r62388023

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have filed issue #6380 to track that. I consider it a blocker.

ax.plot(np.arange(10), 4 * np.arange(10))
ax.plot(np.arange(10), 5 * np.arange(10))

Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/tests/test_rcparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def test_validators():
('cycler(c=[1, 2, 3])', ValueError), # invalid values
("cycler(lw=['a', 'b', 'c'])", ValueError), # invalid values
(cycler('waka', [1, 3, 5]), ValueError), # not a property
(cycler('color', ['C1', 'r', 'g']), ValueError) # no CN
)
},
{'validator': validate_hatch,
Expand Down