Skip to content

[MNT]: matplotlib.cycler and pyplot.cycler are different functions #26868

Open

Description

@timhoffm

Summary

  • pyplot.cycler is an (unused) import of the original cycler.cycler() function. This was originally imported in 0c1e609 to be used inside the xkcd() function. It's probably not meant to be public, but as a matter of fact is now (https://github.com/search?q=plt.cycler&type=code). - We even have used it in an example in 3.4.0 What's new.
  • matplotlib.cycler is matplotlib.rcsetup.cycler() which is a wrapper around cycler.cycler() and additionally includes validation.

Proposed fix

Attention @ksunden: pyplot.cycler is not re-exported for typing, so we may see complaints about this in the near future.


Generally, we should not expose two different cycler functions within matplotlib. It's questionable enough (though one can argue for it) that we provide a replacement for the original cycler.

Likely, the reasonable way forward is to expose matplotlib.rcsetup.cycler() in pyplot.

Activity

  1. added this to the v3.9.0 milestone on Sep 22, 2023
  2. tacaswell commented on Sep 22, 2023

    @tacaswell
    Member

    Likely, the reasonable way forward is to expose matplotlib.rcsetup.cycler() in pyplot.

    I agree

  3. EricRLeao1311 commented on Oct 18, 2023

    @EricRLeao1311

    Good morning. I'm a new contributor and would like to understand what should be done. What we should do, then, is that when the pyplot.cycler function is called, matplotlib.rcsetup.cycler() is called instead. Did I understand correctly?

  4. timhoffm commented on Oct 19, 2023

    @timhoffm
    MemberAuthor

    The key thing to check (and I'm not familiar enough with the cycler logic to do this ad-hoc) is whether matplolib.rcsetup.cycler() is a fully API compatible drop-in replacement for cycler.cycler(), except for the added validation.

    If that's the case, the fix is as easy as replacing

    from cycler import cycler

    by

    from matplotlib.rcsetup import cycler
    

    The main task here is not the code change itself, but to understand the logic and be sure that the change would not break any users.

  5. ksunden commented on Oct 30, 2023

    @ksunden
    Member

    I do believe they are signature compatible, though I will note that part of the validation done by rcsetup.cycler is to limit the valid keys to a known set (not just validate values for a known set of keys). So if someone is using plt.cycler for something other than making a cycler for matplotlib prop cycles, it would break... on the other hand, if they are doing that, they should probably be using cycler directly anyway.

    pyplot.cycler is not re-exported for typing, so we may see complaints about this in the near future.

    Is pyplot really a namespace we wish to advertise cycler is available at? I guess I would actually lean towards taking it out as an implementation detail rather than switching the source... (perhaps as part of a larger cleanup of the pyplot namespace, perhaps with deprecations, etc) if users want the existing cycler method that is there, it should be imported from cycler directly; if you want the validated one get it from rcsetup? I don't have a huge problem with making it technically available. It is not documented in that location (at least in api docs or our own examples; there is one "whats new" entry that uses plt.cycler). It is not used internally by pyplot.py either.

  6. modified the milestones: v3.9.0, v3.10.0 on Apr 3, 2024
  7. timhoffm commented on Oct 28, 2024

    @timhoffm
    MemberAuthor

    Is pyplot really a namespace we wish to advertise cycler is available at?

    cycler is too widely used to just rip it out: https://github.com/search?q=plt.cycler&type=code. Also, it feels too heavy to need an extra import to set a simple colorcycle. - Most of the time people just cycle one property. It might be an option to construct cyclers implicitly in the background, e.g.

    ax.set_prop_cycle({'color': ['r', 'g', 'b']})
    #as a shortcut for
    ax.set_prop_cycle(plt.cycler(color=['r', 'g', 'b']))
    

    That would alleviate the need for most plt.cycler() calls - and may even be simpler as people would not necessarily have to learn about the IMHO quite complex cycler class.

    Defering to 3.11.

    Edit: I just realized ax.set_prop_cycle(color=['r', 'g', 'b']) is already possible. 😆

    With very few exceptions, the other major usage of plt.cycler is in setting rcParams["axes.prop_cycle"] (in all rc setting variants). That currently does not have a shortcut, but one could accept a dict in the validator, i.e. rcParams["axes.prop_cycle"] = {'color': ['r', 'g', 'b']}. I'm 80% the way calling that a reasonable idea.

  8. modified the milestones: v3.10.0, v3.11.0 on Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions