Skip to content

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

Closed

Description

@mdboom

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-`)

Activity

  1. added this to the milestone on Nov 16, 2015
  2. WeatherGod commented on Nov 17, 2015

    @WeatherGod
    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.

  3. mdboom commented on Nov 17, 2015

    @mdboom
    MemberAuthor

    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.

  4. WeatherGod commented on Nov 17, 2015

    @WeatherGod
    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)
    .

  5. mdboom commented on Nov 17, 2015

    @mdboom
    MemberAuthor

    @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.

  6. WeatherGod commented on Nov 17, 2015

    @WeatherGod
    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)
    .

  7. tacaswell commented on Nov 17, 2015

    @tacaswell
    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='-'.

  8. efiring commented on Nov 17, 2015

    @efiring
    Member

    @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.

  9. WeatherGod commented on Nov 17, 2015

    @WeatherGod
    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)
    .

  10. efiring commented on Nov 17, 2015

    @efiring
    Member

    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.

  11. tacaswell commented on Nov 18, 2015

    @tacaswell
    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.

  12. WeatherGod commented on Nov 18, 2015

    @WeatherGod
    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)
    .

  13. efiring commented on Nov 28, 2015

    @efiring
    Member

    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.

  14. mdboom commented on Nov 28, 2015

    @mdboom
    MemberAuthor

    @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.

  15. added 2 commits that reference this issue on Dec 14, 2015
    3780d3b
    4386e35
  16. added a commit that references this issue on Apr 11, 2016
    684dbf6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions