Skip to content

Commit e2625d0

Browse files
authored
Merge pull request #12598 from anntzer/cn
Support Cn colors with n>=10.
2 parents a5901fa + aa96f2d commit e2625d0

File tree

7 files changed

+56
-39
lines changed

7 files changed

+56
-39
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
``Cn`` colors now support ``n>=10``
2+
```````````````````````````````````
3+
4+
It is now possible to go beyond the tenth color in the property cycle using
5+
``Cn`` syntax, e.g. ``plt.plot([1, 2], color="C11")`` now uses the 12th color
6+
in the cycle.
7+
8+
Note that previously, a construct such as ``plt.plot([1, 2], "C11")`` would be
9+
interpreted as a request to use color ``C1`` and marker ``1`` (an "inverted Y").
10+
To obtain such a plot, one should now use ``plt.plot([1, 2], "1C1")`` (so that
11+
the first "1" gets correctly interpreted as a marker specification), or, more
12+
explicitly, ``plt.plot([1, 2], marker="1", color="C1")``.

examples/color/color_demo.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Color Demo
44
==========
55
6-
Matplotlib gives you 8 ways to specify colors,
6+
Matplotlib recognizes the following formats to specify a color:
77
88
1) an RGB or RGBA tuple of float values in ``[0, 1]`` (e.g. ``(0.1, 0.2, 0.5)``
99
or ``(0.1, 0.2, 0.5, 0.3)``). RGBA is short for Red, Green, Blue, Alpha;
@@ -15,10 +15,10 @@
1515
5) a X11/CSS4 ("html") color name, e.g. ``"blue"``;
1616
6) a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__,
1717
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
18-
7) a "Cn" color spec, i.e. `'C'` followed by a single digit, which is an index
19-
into the default property cycle
20-
(``matplotlib.rcParams['axes.prop_cycle']``); the indexing occurs at artist
21-
creation time and defaults to black if the cycle does not include color.
18+
7) a "Cn" color spec, i.e. `'C'` followed by a number, which is an index into
19+
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
20+
indexing is intended to occur at rendering time, and defaults to black if
21+
the cycle does not include color.
2222
8) one of ``{'tab:blue', 'tab:orange', 'tab:green',
2323
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
2424
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the

lib/matplotlib/axes/_axes.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,32 +1526,14 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
15261526
15271527
A format string consists of a part for color, marker and line::
15281528
1529-
fmt = '[color][marker][line]'
1529+
fmt = '[marker][line][color]'
15301530
15311531
Each of them is optional. If not provided, the value from the style
15321532
cycle is used. Exception: If ``line`` is given, but no ``marker``,
15331533
the data will be a line without markers.
15341534
1535-
**Colors**
1536-
1537-
The following color abbreviations are supported:
1538-
1539-
============= ===============================
1540-
character color
1541-
============= ===============================
1542-
``'b'`` blue
1543-
``'g'`` green
1544-
``'r'`` red
1545-
``'c'`` cyan
1546-
``'m'`` magenta
1547-
``'y'`` yellow
1548-
``'k'`` black
1549-
``'w'`` white
1550-
============= ===============================
1551-
1552-
If the color is the only part of the format string, you can
1553-
additionally use any `matplotlib.colors` spec, e.g. full names
1554-
(``'green'``) or hex strings (``'#008000'``).
1535+
Other combinations such as ``[color][marker][line]`` are also
1536+
supported, but note that their parsing may be ambiguous.
15551537
15561538
**Markers**
15571539
@@ -1596,11 +1578,33 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
15961578
Example format strings::
15971579
15981580
'b' # blue markers with default shape
1599-
'ro' # red circles
1600-
'g-' # green solid line
1581+
'or' # red circles
1582+
'-g' # green solid line
16011583
'--' # dashed line with default color
1602-
'k^:' # black triangle_up markers connected by a dotted line
1584+
'^k:' # black triangle_up markers connected by a dotted line
16031585
1586+
**Colors**
1587+
1588+
The supported color abbreviations are the single letter codes
1589+
1590+
============= ===============================
1591+
character color
1592+
============= ===============================
1593+
``'b'`` blue
1594+
``'g'`` green
1595+
``'r'`` red
1596+
``'c'`` cyan
1597+
``'m'`` magenta
1598+
``'y'`` yellow
1599+
``'k'`` black
1600+
``'w'`` white
1601+
============= ===============================
1602+
1603+
and the ``'CN'`` colors that index into the default property cycle.
1604+
1605+
If the color is the only part of the format string, you can
1606+
additionally use any `matplotlib.colors` spec, e.g. full names
1607+
(``'green'``) or hex strings (``'#008000'``).
16041608
"""
16051609
lines = []
16061610

lib/matplotlib/colors.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
5050
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
5151
'T10' categorical palette (which is the default color cycle);
52-
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
53-
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
54-
the indexing occurs at artist creation time and defaults to black if the
52+
* a "CN" color spec, i.e. `'C'` followed by a number, which is an index into
53+
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
54+
indexing is intended to occur at rendering time, and defaults to black if the
5555
cycle does not include color.
5656
5757
All string specifications of color, other than "CN", are case-insensitive.
@@ -115,7 +115,7 @@ def _sanitize_extrema(ex):
115115

116116
def _is_nth_color(c):
117117
"""Return whether *c* can be interpreted as an item in the color cycle."""
118-
return isinstance(c, str) and re.match(r"\AC[0-9]\Z", c)
118+
return isinstance(c, str) and re.match(r"\AC[0-9]+\Z", c)
119119

120120

121121
def is_color_like(c):
@@ -169,7 +169,7 @@ def to_rgba(c, alpha=None):
169169
from matplotlib import rcParams
170170
prop_cycler = rcParams['axes.prop_cycle']
171171
colors = prop_cycler.by_key().get('color', ['k'])
172-
c = colors[int(c[1]) % len(colors)]
172+
c = colors[int(c[1:]) % len(colors)]
173173
try:
174174
rgba = _colors_full_map.cache[c, alpha]
175175
except (KeyError, TypeError): # Not in cache, or unhashable.

lib/matplotlib/tests/test_colors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ def test_cn():
637637
['xkcd:blue', 'r'])
638638
assert mcolors.to_hex("C0") == '#0343df'
639639
assert mcolors.to_hex("C1") == '#ff0000'
640+
assert mcolors.to_hex("C10") == '#0343df'
641+
assert mcolors.to_hex("C11") == '#ff0000'
640642

641643
matplotlib.rcParams['axes.prop_cycle'] = cycler('color', ['8e4585', 'r'])
642644

lib/matplotlib/tests/test_rcparams.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,14 @@ def generate_validator_testcases(valid):
306306
('AABBCC', '#AABBCC'), # RGB hex code
307307
('AABBCC00', '#AABBCC00'), # RGBA hex code
308308
('tab:blue', 'tab:blue'), # named color
309-
('C0', 'C0'), # color from cycle
309+
('C12', 'C12'), # color from cycle
310310
('(0, 1, 0)', [0.0, 1.0, 0.0]), # RGB tuple
311311
((0, 1, 0), (0, 1, 0)), # non-string version
312312
('(0, 1, 0, 1)', [0.0, 1.0, 0.0, 1.0]), # RGBA tuple
313313
((0, 1, 0, 1), (0, 1, 0, 1)), # non-string version
314314
('(0, 1, "0.5")', [0.0, 1.0, 0.5]), # unusual but valid
315315
),
316316
'fail': (('tab:veryblue', ValueError), # invalid name
317-
('C123', ValueError), # invalid RGB(A) code and cycle index
318317
('(0, 1)', ValueError), # tuple with length < 3
319318
('(0, 1, 0, 1, 0)', ValueError), # tuple with length > 4
320319
('(0, 1, none)', ValueError), # cannot cast none to float

tutorials/colors/colors.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
1919
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
2020
'T10' categorical palette (which is the default color cycle);
21-
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
22-
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
23-
the indexing occurs at artist creation time and defaults to black if the
21+
* a "CN" color spec, i.e. `'C'` followed by a number, which is an index into
22+
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
23+
indexing is intended to occur at rendering time, and defaults to black if the
2424
cycle does not include color.
2525
2626
"Red", "Green" and "Blue", are the intensities of those colors, the combination

0 commit comments

Comments
 (0)