-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
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
Conversation
``Cn`` syntax, e.g. ``plt.plot([1, 2], color="C11")`` now uses the 11th color | ||
in the cycle. | ||
|
||
Note that previously, a construct such as ``plt.plot([1, 2], "C11")`` would be |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
``````````````````````````````````` | ||
|
||
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 11th color |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C11
should be the 12th color, right?
In general what happens if you specify Sorry that is indeed tested for.C10
on a cycler with 10 colors? Is it ensured that it will result in the first color then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on whether you think it starts at zeroth or first. I think matching the idex is easier, if not necessarily correct in English.
In any case I think the meaning is clear...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ähm???? Sorry but a[1]
takes the second element of a
, not the first. That has nothing to do with language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, changed.
I would agree that the described API change in the color-marker-whatever-string-minilanguage ( However further documentation changes are necessary: This will require to remove the words "single digit" from
I think this format string language is documented only in the documentatio of
So this should be updated to allow for Also the docs currently say
Here the |
Fixed the docs (moving the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is overall a pretty useful extension. Since it turns out that the format string language hasn't been specified as detailed as to actually support the Cn notation at all and the only breaking case is for digit markers, which are not very popular anyways, this seems like a change that can be made without deprecation.
I am +.5 on this. I see the logic and motivation, but it is now treating strings that used to be equivalent differently. |
You mean the API changes note, or something else? |
I mean the trade off of if the improved functionality worth breaking some (hopefully small number) of users. |
@@ -1517,33 +1517,12 @@ 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]' |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, likeNote 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 the1
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.
There was a problem hiding this comment.
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.
@@ -307,7 +307,7 @@ 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 | |||
('C123', 'C123'), # color from cycle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would just (or additionally) test "C12", which is a pontential ambiguous definition, which is more likely to break when changing the parser code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
+0.5 on this. It's a breaking change, but for a more sane API. I assume that there have been more mistakes made with "C11" intending to get the 11th color, than there have been people, who really wanted to get "C1" with marker "1". Even if I really wanted that, I would have used explicit kwargs, because using "C11" with the marker "1" semantics feels like dirty code. |
If we're really worried about the API break I can probably make "C11" (as an arg, not a kwarg) still keep its old meaning; at least prople will now be able to use |
I agree, I think that would be worse than breaking 'C11' vs '1C1' equivalence. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine. The obscure API break is pretty obscure and easily worked around.
@anntzer is this ready to merge, or were you still playing w. it? |
@tacaswell asked @WeatherGod to review this, let's give him a few more days to chime in. |
ping @WeatherGod - we'll merge if we don't hear from you by, say, Friday? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am +0 on this. I really don't see the point of needing this many colors in your graph, and if you did need that many colors, to have a need to access those upper colors through a mechanism that was intended for simple scripts and interactive uses. If you are plotting that many things to need that many colors, I sure hope you have some loops in your code, in which case, it isn't that difficult to get the colors yourself.
The fact that this introduces a slight change in interpretation is concerning, but not the end-of-the-world. CN notation has not been around for very long, and '1C1' is more readable than 'C11'.
We need to do something about the documentation stating that the color is indexed at artist creation time. That may have been the original intent, but it certainly isn't always the case now, and I think "at the time of rendering" makes more sense as a target goal. At the very least, we should throw out this statement and leave it ambiguous until we solve the issue across the board.
examples/color/color_demo.py
Outdated
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 occurs at artist creation time and defaults to black if the cycle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while we are here, we should fix this statement "at artist creation time" and make it "at the time of rendering". I know we aren't quite there yet, but this current statement isn't true, either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also mention that this is a goal and we‘re not yet there. Having an uncommitted false statement in the docs is misleading.
lib/matplotlib/colors.py
Outdated
cycle does not include color. | ||
* 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 occurs at artist creation time and defaults to black if the cycle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto here. "artist creation time" --> "at the time of rendering"
tutorials/colors/colors.py
Outdated
cycle does not include color. | ||
* 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 occurs at artist creation time and defaults to black if the cycle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto here, too.
Actually another use case (which motivated this PR to start with) is to rely on cycling, e.g. having only 10 colors in the cycle but wanting to plot 20 lines, then you can just color them with C0...C19 without bothering of doing things modulo... well you can't even do it modulo len(prop_cycle) because 1) I think there isn't a getter on the prop cycle? and more importantly 2) the prop cycle that matters is the one at rendering time, which we don't know yet. |
While the change is mildly backwards-incompatible (as noted in the API changes), Cn syntax is by far the simplest way to navigate the color-cycle, so I think the change is worth it.
Updated the docs with "... is intended to occur at rendering time" given that the current behavior is a mess... (would be nice to reach a decision wrt #11711, btw) |
Yes, the wording is much better. I am still +0 on this, so I will dismiss my request for changes to unblock this.
While the change is mildly backwards-incompatible (as noted in the API
changes), Cn syntax is by far the simplest way to navigate the
color-cycle, so I think the change is worth it.
PR Summary
PR Checklist