Skip to content

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

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

Open
timhoffm opened this issue Sep 22, 2023 · 5 comments · May be fixed by #27210
Open

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

timhoffm opened this issue Sep 22, 2023 · 5 comments · May be fixed by #27210
Milestone

Comments

@timhoffm
Copy link
Member

timhoffm commented Sep 22, 2023

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.

@tacaswell tacaswell added this to the v3.9.0 milestone Sep 22, 2023
@tacaswell
Copy link
Member

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

I agree

@EricRLeao1311
Copy link

EricRLeao1311 commented Oct 18, 2023

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?

@timhoffm
Copy link
Member Author

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.

@EricRLeao1311 EricRLeao1311 linked a pull request Oct 26, 2023 that will close this issue
5 tasks
@ksunden
Copy link
Member

ksunden commented Oct 30, 2023

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.

@QuLogic QuLogic modified the milestones: v3.9.0, v3.10.0 Apr 3, 2024
@timhoffm
Copy link
Member Author

timhoffm commented Oct 28, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants