Skip to content
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

Special color names to pull colors from the currently active color cycle #5489

Closed
mdboom opened this issue Nov 16, 2015 · 13 comments
Closed
Milestone

Comments

@mdboom
Copy link
Member

mdboom commented Nov 16, 2015

It would be extremely convenient to be able to choose colors from the current color cycle in the special syntax we support as a third argument to plt.plot. We proposed using [n] for this, where n is the index into the current color cycle. Eg.:

plt.plot(x, y, `[1]o-`)
@mdboom mdboom added this to the next major release (2.0) milestone Nov 16, 2015
@WeatherGod
Copy link
Member

Two problems: 1) cyclers are not indexable and not easily inspectable. That
is why I came up with doing validation prior to creating the cyclers. 2)
there will be ambiguity about what the notation refers to. Color cycles are
deprecated, replaced by property cycles, which may or may not cycle colors.
On Nov 16, 2015 5:26 PM, "Michael Droettboom" notifications@github.com
wrote:

It would be extremely convenient to be able to choose colors from the
current color cycle in the special syntax we support as a third argument to
plt.plot. We proposed using [n] for this, where n is the index into the
current color cycle. Eg.:

plt.plot(x, y, [1]o-)


Reply to this email directly or view it on GitHub
#5489.

@mdboom
Copy link
Member Author

mdboom commented Nov 17, 2015

Yes -- I agree with all that. But I still think the utility of this is too great not to find a way to make work.

The motivation is this: It's very common to see people plot a line, then some markers, then some bars all with the same color because that data is somehow "related". Right now, that's really easy because many use the single character color names (r, etc.). When we move to a default style that has more "complex" colors that don't map to the single character color names, it would be desirable to still support a way to do that. The only other way I can think of is if we start requiring that the user explicitly step the property cycle. But I don't think that's going to fly.

@WeatherGod
Copy link
Member

Counter-proposal:

What if we made this example:
https://github.com/matplotlib/cycler/blob/master/doc/source/index.rst#persistent-cycles
even easier? Essentially, when someone plots something with a label, that
label becomes a key to an internal defaultdict of plotting properties. If
the key didn't exist already, then it would advance the cycler and store
those properties. If the key exists, it will use that and not advance the
cycler. No new special notations that require parsing and possibly cause
confusion. Just utilize the label kwarg (or maybe another kwarg if we don't
want to cross the streams).

On Mon, Nov 16, 2015 at 9:40 PM, Michael Droettboom <
notifications@github.com> wrote:

Yes -- I agree with all that. But I still think the utility of this is too
great not to find a way to make work.

The motivation is this: It's very common to see people plot a line, then
some markers, then some bars all with the same color because that data is
somehow "related". Right now, that's really easy because many use the
single character color names (r, etc.). When we move to a default style
that has more "complex" colors that don't map to the single character color
names, it would be desirable to still support a way to do that. The only
other way I can think of is if we start requiring that the user explicitly
step the property cycle. But I don't think that's going to fly.


Reply to this email directly or view it on GitHub
#5489 (comment)
.

@mdboom
Copy link
Member Author

mdboom commented Nov 17, 2015

@WeatherGod: That's an interesting proposal. Particularly because it keeps the whole cycler (not just its color aspect) in play. I am worried about overriding label. What if the [n] notation (which would be a new addition to the short-form style stuff like bo- that one can do now) was used for this. I suppose in that case n doesn't even have to be a number, just a unique key.

@WeatherGod
Copy link
Member

Personally, I would like to avoid adding new notations to plot().
Furthermore, it doesn't really help us for other plotting commands such as
bar(), hist(), etc.

On Tue, Nov 17, 2015 at 9:50 AM, Michael Droettboom <
notifications@github.com> wrote:

@WeatherGod https://github.com/WeatherGod: That's an interesting
proposal. Particularly because it keeps the whole cycler (not just its
color aspect) in play. I am worried about overriding label. What if the
[n] notation (which would be a new addition to the short-form style stuff
like bo- that one can do now) was used for this. I suppose in that case n
doesn't even have to be a number, just a unique key.


Reply to this email directly or view it on GitHub
#5489 (comment)
.

@tacaswell
Copy link
Member

A surprising number plotting methods do accept a fmt arg.

There is a stand-alone function which parses the fmt string into a tuple, it would be easy enough to convert that into a function returns a dict which we can then throw into the vapor-ware kwargs normalization and have every function take a fmt string. It is super ugly, but 'bo-' is so much more concise than color='b', marker='o', linestyle='-'.

@efiring
Copy link
Member

efiring commented Nov 17, 2015

@WeatherGod I don't think your proposal entirely addresses the basic use case: a user, not a programmer--and maybe a relatively new user, or an occasional user--just wants to be able to get a known consistent color with the fewest characters possible, in a way that is as easy to remember as possible. It might be in a plot command, it might be something else. Old style: 'b', 'g', 'r', etc. New style: the user wants the first or second or third color in the default cycle, because these colors are familiar and they look nice. It has to be easy, repeatable, easy to remember, and not require any fiddling with cyclers, dicts, etc. Just a simple, short string. It should be usable anywhere a colorspec is accepted, as well as in the hard-to-parse-but-convenient 'bo' style plot specification.

@WeatherGod
Copy link
Member

my proposal does not require any fiddling with cyclers for the users. It
only requires adding a label to your plot. The only thing you lose is the
ability to explicitly state which element in the cycle you want, which I
highly doubt is actually useful, and it would be extremely difficult to
implement correctly. Instead, you reference your plotting element by name,
and whatever property spec that comes up will get reused if you use that
name again anyplace else.

plt.plot(x1, y1, '[foo]')
plt.bar(x1, y2, '[bar]')
plt.bar(x1, y1, '[foo]')  # reuse the property spec used for the first
plot() call

What could be easier than that?

Still not crazy about the call signature handling, as we have seen how
difficult this has been for handling the labeled data stuff, but I could
grow to accept that. Otherwise, we could introduce a new kwarg.

On Tue, Nov 17, 2015 at 5:04 PM, Eric Firing notifications@github.com
wrote:

@WeatherGod https://github.com/WeatherGod I don't think your proposal
entirely addresses the basic use case: a user, not a programmer--and maybe
a relatively new user, or an occasional user--just wants to be able to get
a known consistent color with the fewest characters possible, in a way that
is as easy to remember as possible. It might be in a plot command, it might
be something else. Old style: 'b', 'g', 'r', etc. New style: the user wants
the first or second or third color in the default cycle, because these
colors are familiar and they look nice. It has to be easy, repeatable, easy
to remember, and not require any fiddling with cyclers, dicts, etc. Just a
simple, short string. It should be usable anywhere a colorspec is accepted,
as well as in the hard-to-parse-but-convenient 'bo' style plot
specification.


Reply to this email directly or view it on GitHub
#5489 (comment)
.

@efiring
Copy link
Member

efiring commented Nov 17, 2015

On 2015/11/17 12:16 PM, Benjamin Root wrote:

my proposal does not require any fiddling with cyclers for the users. It
only requires adding a label to your plot. The only thing you lose is the
ability to explicitly state which element in the cycle you want, which I
highly doubt is actually useful, and it would be extremely difficult to
implement correctly. Instead, you reference your plotting element by name,
and whatever property spec that comes up will get reused if you use that
name again anyplace else.

plt.plot(x1, y1, '[foo]')
plt.bar(x1, y2, '[bar]')
plt.bar(x1, y1, '[foo]') # reuse the property spec used for the first
plot() call

What could be easier than that?

This doesn't address my use cases. The user wants a specific color,
not necessarily a full spec; and it might be used for a patch, or text,
or whatever. And it might be wanted in a context where there has been
no call to plot, etc.

@tacaswell
Copy link
Member

Tying into the labels also means that the color lookup is now axes dependent, where as the '[n]' lookup can only depend on the default cycle.

@WeatherGod
Copy link
Member

If you want a specific color, then specify that you want that color. The
problem with accessing a particular element for a particular property is
that the information you want is not easily retrievable that way (we would
need some new features added to cycler first) and that particular property
may not even be defined for the cycle. Neither of those problems are
insurmountable, but it seems like a lot of work for something that would be
of very limited utility (I.e., you need to know which index and it can only
be for colors).

As for it being tied to an axes, that is an implementation detail that
needs to be sorted out. We can put the defaultdict at the axes, figure, or
even at the global level. There are pros and cons at different levels.
On Nov 17, 2015 8:12 PM, "Thomas A Caswell" notifications@github.com
wrote:

Tying into the labels also means that the color lookup is now axes
dependent, where as the '[n]' lookup can only depend on the default cycle.


Reply to this email directly or view it on GitHub
#5489 (comment)
.

@efiring
Copy link
Member

efiring commented Nov 28, 2015

Nothing needs to be added to Cycler; the _transpose() method provides exactly what is needed, provided the Cycler uses only addition. The way to ensure there is a color key and there is no multiplication is to start with a Cycler that has one; eliminating the "color_cycle" in favor of a "prop_cycle" might be an API mistake. Instead, keep a base default color_cycle, which the user might or might not combine with something else, or replace with something else, in the prop_cycle.

@mdboom
Copy link
Member Author

mdboom commented Nov 28, 2015

@efiring: I've been thinking the same thing as I'm working through #5577 and the other style changes. The property cycle is nice when talking about line and marker plots, but for other things (errorbar, for example, which are made up of many discrete elements) you just want the color.

mdboom added a commit to mdboom/matplotlib that referenced this issue Dec 14, 2015
mdboom added a commit to mdboom/matplotlib that referenced this issue Dec 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants