Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support Cn colors with n>=10. #12598

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 1 commit into from
Nov 5, 2018
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: 12 additions & 0 deletions doc/api/next_api_changes/2018-10-23-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
``Cn`` colors now support ``n>=10``
```````````````````````````````````

It is now possible to go beyond the tenth color in the property cycle using
``Cn`` syntax, e.g. ``plt.plot([1, 2], color="C11")`` now uses the 12th color
in the cycle.

Note that previously, a construct such as ``plt.plot([1, 2], "C11")`` would be
Copy link
Member

Choose a reason for hiding this comment

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

Are there any gallary examples that need to be updated to show this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A quick grep doesn't yield anything relevant.

interpreted as a request to use color ``C1`` and marker ``1`` (an "inverted Y").
To obtain such a plot, one should now use ``plt.plot([1, 2], "1C1")`` (so that
the first "1" gets correctly interpreted as a marker specification), or, more
explicitly, ``plt.plot([1, 2], marker="1", color="C1")``.
10 changes: 5 additions & 5 deletions examples/color/color_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Color Demo
==========

Matplotlib gives you 8 ways to specify colors,
Matplotlib recognizes the following formats to specify a color:

1) an RGB or RGBA tuple of float values in ``[0, 1]`` (e.g. ``(0.1, 0.2, 0.5)``
or ``(0.1, 0.2, 0.5, 0.3)``). RGBA is short for Red, Green, Blue, Alpha;
Expand All @@ -15,10 +15,10 @@
5) a X11/CSS4 ("html") color name, e.g. ``"blue"``;
6) a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__,
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
7) a "Cn" color spec, i.e. `'C'` followed by a single digit, which is an index
into the default property cycle
(``matplotlib.rcParams['axes.prop_cycle']``); the indexing occurs at artist
creation time and defaults to black if the cycle does not include color.
7) a "Cn" color spec, i.e. `'C'` followed by a number, which is an index into
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
indexing is intended to occur at rendering time, and defaults to black if
the cycle does not include color.
8) one of ``{'tab:blue', 'tab:orange', 'tab:green',
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
Expand Down
52 changes: 28 additions & 24 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1517,32 +1517,14 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):

A format string consists of a part for color, marker and line::

fmt = '[color][marker][line]'
fmt = '[marker][line][color]'
Copy link
Member

Choose a reason for hiding this comment

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

Not sure it is worth to make that change. Anyway we should explicitly state that order does not matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it does in the sense that C11 doesn't mean the same thing as 1C1.

Copy link
Member

Choose a reason for hiding this comment

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

I feel that 'b-' is much more used in practical code than '-b'. Maybe also because of the current docs. I wouldn't want to change the habits of users for that. 'C11' really an edge case, and is just now eagerly collecting digits. People can still go for '1C1' in that specific case (or use kwargs), I would not generally recommend switching the order.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not recommanding it (or even coming closing to thinking about deprecating the other order); I'm just putting the docs in the order that always works...
At least if by any chance a new user discovers the minilanguage by reading this specific docstring (which likely never happens), they'll have it in the right order.

Choose a reason for hiding this comment

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

Two options:

  • Leave fmt = '[color][marker][line] as before. Add a sentence about the potential problem, like

    Note that this may lead to an ambiguity when using single digit markers ("1") in combination with the "Cn" color notation, i.e. "C11" means the twelfth color without marker. To provide the option to use the 1 marker and the second color, use "1C1".

    Keep the rest of the docstring the same.

  • Change it to fmt = '[marker][line][color]'. In that case add a sentence like,

    Note that other combinations like [color][marker][line] are equally supported but might lead to ambiguities concerning colors and markers.

    Then change the example strings further down the page to match with the new format.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

add a sentence like,

Note that other combinations like [color][marker][line] are equally supported but might lead to ambiguities concerning colors and markers.

Done.

Then change the example strings further down the page to match with the new format.

That was already done.


Each of them is optional. If not provided, the value from the style
cycle is used. Exception: If ``line`` is given, but no ``marker``,
the data will be a line without markers.

**Colors**

The following color abbreviations are supported:

============= ===============================
character color
============= ===============================
``'b'`` blue
``'g'`` green
``'r'`` red
``'c'`` cyan
``'m'`` magenta
``'y'`` yellow
``'k'`` black
``'w'`` white
============= ===============================

If the color is the only part of the format string, you can
additionally use any `matplotlib.colors` spec, e.g. full names
(``'green'``) or hex strings (``'#008000'``).
Other combinations such as ``[color][marker][line]`` are also
supported, but note that their parsing may be ambiguous.

**Markers**

Expand Down Expand Up @@ -1587,11 +1569,33 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
Example format strings::

'b' # blue markers with default shape
'ro' # red circles
'g-' # green solid line
'or' # red circles
'-g' # green solid line
'--' # dashed line with default color
'k^:' # black triangle_up markers connected by a dotted line
'^k:' # black triangle_up markers connected by a dotted line

**Colors**

The supported color abbreviations are the single letter codes

============= ===============================
character color
============= ===============================
``'b'`` blue
``'g'`` green
``'r'`` red
``'c'`` cyan
``'m'`` magenta
``'y'`` yellow
``'k'`` black
``'w'`` white
============= ===============================

and the ``'CN'`` colors that index into the default property cycle.

If the color is the only part of the format string, you can
additionally use any `matplotlib.colors` spec, e.g. full names
(``'green'``) or hex strings (``'#008000'``).
"""
lines = []

Expand Down
10 changes: 5 additions & 5 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
'T10' categorical palette (which is the default color cycle);
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
the indexing occurs at artist creation time and defaults to black if the
* a "CN" color spec, i.e. `'C'` followed by a number, which is an index into
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
indexing is intended to occur at rendering time, and defaults to black if the
cycle does not include color.

All string specifications of color, other than "CN", are case-insensitive.
Expand Down Expand Up @@ -115,7 +115,7 @@ def _sanitize_extrema(ex):

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


def is_color_like(c):
Expand Down Expand Up @@ -169,7 +169,7 @@ def to_rgba(c, alpha=None):
from matplotlib import rcParams
prop_cycler = rcParams['axes.prop_cycle']
colors = prop_cycler.by_key().get('color', ['k'])
c = colors[int(c[1]) % len(colors)]
c = colors[int(c[1:]) % len(colors)]
try:
rgba = _colors_full_map.cache[c, alpha]
except (KeyError, TypeError): # Not in cache, or unhashable.
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ def test_cn():
['xkcd:blue', 'r'])
assert mcolors.to_hex("C0") == '#0343df'
assert mcolors.to_hex("C1") == '#ff0000'
assert mcolors.to_hex("C10") == '#0343df'
assert mcolors.to_hex("C11") == '#ff0000'

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

Expand Down
3 changes: 1 addition & 2 deletions lib/matplotlib/tests/test_rcparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,15 +306,14 @@ def generate_validator_testcases(valid):
('AABBCC', '#AABBCC'), # RGB hex code
('AABBCC00', '#AABBCC00'), # RGBA hex code
('tab:blue', 'tab:blue'), # named color
('C0', 'C0'), # color from cycle
('C12', 'C12'), # color from cycle
('(0, 1, 0)', [0.0, 1.0, 0.0]), # RGB tuple
((0, 1, 0), (0, 1, 0)), # non-string version
('(0, 1, 0, 1)', [0.0, 1.0, 0.0, 1.0]), # RGBA tuple
((0, 1, 0, 1), (0, 1, 0, 1)), # non-string version
('(0, 1, "0.5")', [0.0, 1.0, 0.5]), # unusual but valid
),
'fail': (('tab:veryblue', ValueError), # invalid name
('C123', ValueError), # invalid RGB(A) code and cycle index
('(0, 1)', ValueError), # tuple with length < 3
('(0, 1, 0, 1, 0)', ValueError), # tuple with length > 4
('(0, 1, none)', ValueError), # cannot cast none to float
Expand Down
6 changes: 3 additions & 3 deletions tutorials/colors/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
'T10' categorical palette (which is the default color cycle);
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
the indexing occurs at artist creation time and defaults to black if the
* a "CN" color spec, i.e. `'C'` followed by a number, which is an index into
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
indexing is intended to occur at rendering time, and defaults to black if the
cycle does not include color.

"Red", "Green" and "Blue", are the intensities of those colors, the combination
Expand Down