Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 595868a

Browse filesBrowse files
committed
Merge pull request #5452 from u55/cycler_generic_iterator
Fix axes.set_prop_cycle to handle any generic iterable sequence.
2 parents 838502e + 3571921 commit 595868a
Copy full SHA for 595868a

File tree

Expand file treeCollapse file tree

3 files changed

+83
-7
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+83
-7
lines changed

‎lib/matplotlib/rcsetup.py

Copy file name to clipboardExpand all lines: lib/matplotlib/rcsetup.py
+11-2Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
import operator
2323
import os
2424
import warnings
25+
try:
26+
import collections.abc as abc
27+
except ImportError:
28+
# python 2
29+
import collections as abc
2530
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
2631
from matplotlib.colors import is_color_like
2732

@@ -78,15 +83,19 @@ def f(s):
7883
return [scalar_validator(v.strip()) for v in s if v.strip()]
7984
else:
8085
raise
81-
elif type(s) in (list, tuple):
86+
# We should allow any generic sequence type, including generators,
87+
# Numpy ndarrays, and pandas data structures. However, unordered
88+
# sequences, such as sets, should be allowed but discouraged unless the
89+
# user desires pseudorandom behavior.
90+
elif isinstance(s, abc.Iterable) and not isinstance(s, abc.Mapping):
8291
# The condition on this list comprehension will preserve the
8392
# behavior of filtering out any empty strings (behavior was
8493
# from the original validate_stringlist()), while allowing
8594
# any non-string/text scalar values such as numbers and arrays.
8695
return [scalar_validator(v) for v in s
8796
if not isinstance(v, six.string_types) or v]
8897
else:
89-
msg = "'s' must be of type [ string | list | tuple ]"
98+
msg = "{0!r} must be of type: string or non-dictionary iterable.".format(s)
9099
raise ValueError(msg)
91100
f.__doc__ = scalar_validator.__doc__
92101
return f

‎lib/matplotlib/tests/test_cycles.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_cycles.py
+61-1Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from matplotlib.testing.decorators import image_comparison
1+
from matplotlib.testing.decorators import image_comparison, cleanup
22
import matplotlib.pyplot as plt
33
import numpy as np
4+
from nose.tools import assert_raises
45

56
from cycler import cycler
67

@@ -42,6 +43,27 @@ def test_marker_cycle():
4243
ax.legend(loc='upper left')
4344

4445

46+
# Reuse the image from test_marker_cycle()
47+
@image_comparison(baseline_images=['marker_cycle'], remove_text=True,
48+
extensions=['png'])
49+
def test_marker_cycle_keywords():
50+
fig = plt.figure()
51+
ax = fig.add_subplot(111)
52+
# Test keyword arguments, numpy arrays, and generic iterators
53+
ax.set_prop_cycle(color=np.array(['r', 'g', 'y']),
54+
marker=iter(['.', '*', 'x']))
55+
xs = np.arange(10)
56+
ys = 0.25 * xs + 2
57+
ax.plot(xs, ys, label='red dot', lw=4, ms=16)
58+
ys = 0.45 * xs + 3
59+
ax.plot(xs, ys, label='green star', lw=4, ms=16)
60+
ys = 0.65 * xs + 4
61+
ax.plot(xs, ys, label='yellow x', lw=4, ms=16)
62+
ys = 0.85 * xs + 5
63+
ax.plot(xs, ys, label='red2 dot', lw=4, ms=16)
64+
ax.legend(loc='upper left')
65+
66+
4567
@image_comparison(baseline_images=['lineprop_cycle_basic'], remove_text=True,
4668
extensions=['png'])
4769
def test_linestylecycle_basic():
@@ -104,6 +126,44 @@ def test_fillcycle_ignore():
104126
ax.legend(loc='upper left')
105127

106128

129+
@cleanup
130+
def test_valid_input_forms():
131+
fig, ax = plt.subplots()
132+
# These should not raise an error.
133+
ax.set_prop_cycle(None)
134+
ax.set_prop_cycle(cycler('linewidth', [1, 2]))
135+
ax.set_prop_cycle('color', 'rgywkbcm')
136+
ax.set_prop_cycle('linewidth', (1, 2))
137+
ax.set_prop_cycle('linewidth', [1, 2])
138+
ax.set_prop_cycle('linewidth', iter([1, 2]))
139+
ax.set_prop_cycle('linewidth', np.array([1, 2]))
140+
ax.set_prop_cycle('color', np.array([[1, 0, 0],
141+
[0, 1, 0],
142+
[0, 0, 1]]))
143+
ax.set_prop_cycle(lw=[1, 2], color=['k', 'w'], ls=['-', '--'])
144+
ax.set_prop_cycle(lw=np.array([1, 2]),
145+
color=np.array(['k', 'w']),
146+
ls=np.array(['-', '--']))
147+
assert True
148+
149+
150+
@cleanup
151+
def test_invalid_input_forms():
152+
fig, ax = plt.subplots()
153+
with assert_raises((TypeError, ValueError)):
154+
ax.set_prop_cycle(1)
155+
with assert_raises((TypeError, ValueError)):
156+
ax.set_prop_cycle([1, 2])
157+
with assert_raises((TypeError, ValueError)):
158+
ax.set_prop_cycle('color', 'fish')
159+
with assert_raises((TypeError, ValueError)):
160+
ax.set_prop_cycle('linewidth', 1)
161+
with assert_raises((TypeError, ValueError)):
162+
ax.set_prop_cycle('linewidth', {'1': 1, '2': 2})
163+
with assert_raises((TypeError, ValueError)):
164+
ax.set_prop_cycle(linewidth=1, color='r')
165+
166+
107167
if __name__ == '__main__':
108168
import nose
109169
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

‎lib/matplotlib/tests/test_rcparams.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_rcparams.py
+11-4Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,15 @@ def test_validators():
280280
('aardvark, ,', ['aardvark']),
281281
(['a', 'b'], ['a', 'b']),
282282
(('a', 'b'), ['a', 'b']),
283-
((1, 2), ['1', '2'])),
284-
'fail': ((dict(), ValueError),
285-
(1, ValueError),)
286-
},
283+
(iter(['a', 'b']), ['a', 'b']),
284+
(np.array(['a', 'b']), ['a', 'b']),
285+
((1, 2), ['1', '2']),
286+
(np.array([1, 2]), ['1', '2']),
287+
),
288+
'fail': ((dict(), ValueError),
289+
(1, ValueError),
290+
)
291+
},
287292
{'validator': validate_nseq_int(2),
288293
'success': ((_, [1, 2])
289294
for _ in ('1, 2', [1.5, 2.5], [1, 2],
@@ -353,6 +358,8 @@ def test_validators():
353358
(['', 'g', 'blue'], ['g', 'blue']),
354359
([np.array([1, 0, 0]), np.array([0, 1, 0])],
355360
np.array([[1, 0, 0], [0, 1, 0]])),
361+
(np.array([[1, 0, 0], [0, 1, 0]]),
362+
np.array([[1, 0, 0], [0, 1, 0]])),
356363
),
357364
'fail': (('fish', ValueError),
358365
),

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.