GithubHelp home page GithubHelp logo

matplotlib / cycler Goto Github PK

View Code? Open in Web Editor NEW
70.0 29.0 50.0 2.42 MB

cycler: composable cycles

Home Page: https://matplotlib.org/cycler/

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%

cycler's Introduction

cycler's People

Contributors

afvincent avatar alimuhammadofficial avatar anntzer avatar ayushman17 avatar danielballan avatar efiring avatar ewouth avatar hugovk avatar importanceofbeingernest avatar jenshnielsen avatar johnthagen avatar kojoley avatar ksunden avatar mdboom avatar oscargus avatar pelson avatar qulogic avatar tacaswell avatar timhoffm avatar toddrme2178 avatar weathergod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cycler's Issues

Add concatenation operator

Candidate operator is & such that cycler('c', 'rgb') & cycler('c', 'cmyk') == cycler('c', 'rgbcmyk')

If the keys do not match exactly, raises.

Include tests in release

Please include tests in the archives of releases. This makes it easier for packagers to test whether their packaged version works. Thanks!

New cycler build on PyPI.org?

Good day,
I just want to ask to make a new build of this lib. In https://pypi.org/project/Cycler/ there is last version from 2016-02-16 .
Probably you do not have new feature, but anyway there are some minor fixes like adding LICENSE into metadata directory of this project / Py package.
(This would help to make some license things of my project 100% clear as your BSD license says: "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer." But you as the author do not ship it now within the package on PyPI.org...)
Please, could you issue higher version of cycler? (E.g. v0.10.1 ?)
Thank you.

0.10.0: pytest warnings

+ /usr/bin/python3 -Bm pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.9, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /home/tkloczko/rpmbuild/BUILD/cycler-0.10.0
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, expect-1.1.0, cov-2.11.1, httpbin-1.0.0, xdist-2.2.1, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, pyfakefs-4.4.0, freezegun-0.4.2, cases-3.4.6, case-1.5.3, isort-1.3.0, aspectlib-1.5.2, asyncio-0.15.1, toolbox-0.5, xprocess-0.17.1, flaky-3.7.0, requests-mock-1.9.2, aiohttp-0.3.0, checkdocs-2.7.0, mock-3.6.1, hypothesis-6.13.2
collected 22 items

. .                                                                                                                                                                  [  4%]
test_cycler.py xxxx.xx.x.x...x....xx                                                                                                                                 [100%]

============================================================================= warnings summary =============================================================================
test_cycler.py:27
  test_cycler.py:27: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_creation will be ignored
    def test_creation():

test_cycler.py:36
  test_cycler.py:36: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_compose will be ignored
    def test_compose():

test_cycler.py:59
  test_cycler.py:59: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_inplace will be ignored
    def test_inplace():

test_cycler.py:72
  test_cycler.py:72: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_constructor will be ignored
    def test_constructor():

test_cycler.py:107
  test_cycler.py:107: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_simplify will be ignored
    def test_simplify():

test_cycler.py:114
  test_cycler.py:114: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_multiply will be ignored
    def test_multiply():

test_cycler.py:131
  test_cycler.py:131: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_getitem will be ignored
    def test_getitem():

test_cycler.py:154
  test_cycler.py:154: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_repr will be ignored
    def test_repr():

test_cycler.py:259
  test_cycler.py:259: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_eq will be ignored
    def test_eq():

test_cycler.py:316
  test_cycler.py:316: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_by_key_add will be ignored
    def test_by_key_add():

test_cycler.py:324
  test_cycler.py:324: PytestCollectionWarning: yield tests were removed in pytest 4.0 - test_by_key_mul will be ignored
    def test_by_key_mul():

-- Docs: https://docs.pytest.org/en/stable/warnings.html
========================================================================= short test summary info ==========================================================================
XFAIL test_cycler.py::test_creation
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_creation will be ignored
XFAIL test_cycler.py::test_compose
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_compose will be ignored
XFAIL test_cycler.py::test_inplace
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_inplace will be ignored
XFAIL test_cycler.py::test_constructor
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_constructor will be ignored
XFAIL test_cycler.py::test_simplify
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_simplify will be ignored
XFAIL test_cycler.py::test_multiply
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_multiply will be ignored
XFAIL test_cycler.py::test_getitem
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_getitem will be ignored
XFAIL test_cycler.py::test_repr
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_repr will be ignored
XFAIL test_cycler.py::test_eq
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_eq will be ignored
XFAIL test_cycler.py::test_by_key_add
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_by_key_add will be ignored
XFAIL test_cycler.py::test_by_key_mul
  reason: [NOTRUN] yield tests were removed in pytest 4.0 - test_by_key_mul will be ignored
=============================================================== 11 passed, 11 xfailed, 11 warnings in 6.79s ================================================================

Peusdo-infinite cycle

It could be useful to have the possibility to define a pseudo-infinite cycle which gives some first colors and then use the last one defined in the cycle.

Why this could be useful ? When you have several curves, it could be better to just colorize some curves to highlight them whereas the others are less important but you still need to show them in gray for example.

Here is an example : see the rule 8.

doc: fix compatibility with ipython 7.11+

Hello,
since we introduced ipython 7.11 in Debian cycler failed to build its documentation, the fix is pretty straightforward:

--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -48,8 +48,6 @@ hashable (as it will eventually be used
 
    from __future__ import print_function
    from cycler import cycler
-
-
    color_cycle = cycler(color=['r', 'g', 'b'])
    color_cycle

can you please apply it? thanks!

0.10.0: cycler test suite is using `nose` module

nose module is for python 2.x and for 3.x id deprecated https://nose.readthedocs.io/en/latest/
I recommend use pytest

+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
Using --randomly-seed=1022359813
rootdir: /home/tkloczko/rpmbuild/BUILD/cycler-0.10.0
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, expect-1.1.0, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, freezegun-0.4.2, aspectlib-1.5.2, toolbox-0.5, rerunfailures-9.1.1, requests-mock-1.9.3, cov-2.12.1, flaky-3.7.0, benchmark-3.4.1, xdist-2.3.0, pylama-7.7.1, datadir-1.3.1, regressions-2.2.0, cases-3.6.3, xprocess-0.18.1, black-0.3.12, anyio-3.3.0, asyncio-0.15.1, trio-0.7.0, subtests-0.5.0, isort-2.0.0, hypothesis-6.14.6, mock-3.6.1, profiling-1.7.0, randomly-3.8.0, Faker-8.12.1, nose2pytest-1.0.8, pyfakefs-4.5.1, tornado-0.8.1, twisted-1.13.3
collected 0 items / 1 error

================================================================================== ERRORS ==================================================================================
_____________________________________________________________________ ERROR collecting test_cycler.py ______________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/cycler-0.10.0/test_cycler.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
test_cycler.py:6: in <module>
    from nose.tools import (assert_equal, assert_not_equal,
E   ModuleNotFoundError: No module named 'nose'
========================================================================= short test summary info ==========================================================================
ERROR test_cycler.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================= 1 error in 0.32s =============================================================================
pytest-xprocess reminder::Be sure to terminate the started process by running 'pytest --xkill' if you have not explicitly done so in your fixture with 'xprocess.getinfo(<process_name>).terminate()'.

LICENSE file missing from latest release

Tools such as pip-licenses use the LICENSE file included in uploaded Python packages to generate license reports. The latest release of cycler does not have a LICENSE file included which makes it more challenging to comply with the license.

Could a new release of cycler be released using the latest wheel library that pulls in the LICENSE file via:

license_file = LICENSE

cross product yields cycler which repeats property values (not really cycling, then)

Bug report

Bug summary

Composing two property cyclers yields a cycler which stays on one property value for multiple calls

from matplotlib.pyplot import cycler

prop_orders = {
    'color': ['k', 'r', 'g', 'b', 'c', 'm', 'y'],
    'marker': ['.', 'o', 'v', 's', '*'],
    'linestyle': ['-', '--', '-.', ':'],
    'hatch': ('-', '+', 'x', '\\', '*', 'o', 'O', '.'),
}

a=cycler('color', prop_orders['color'])
b=cycler('marker', prop_orders['marker'])

c = (a*b)()

print(next(c))
print(next(c))

Actual outcome

{'color': 'k', 'marker': '.'}
{'color': 'k', 'marker': 'o'}

Expected outcome
I would expect both attributes to be actively cycling, i.e.

{'color': 'k', 'marker': '.'}
{'color': 'r', 'marker': 'o'}

Matplotlib version

  • Operating system: Ubuntu 18.04
  • Matplotlib version: 3.0.2
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.6.8 (Anaconda)
  • Jupyter version (if applicable): n/a
  • Other libraries:

(mini)conda installation

Please ship tests to pypi

the pypi tarball is not containing the run_tests.py. Downstream distro packager like to run tests on their system to see that everything is working. Please ship the test script in the pypi tarball.

ValueError: Can only use slices with Cycler.getitem

I'm try to plot my data, this shows this error.

ValueError: Can only use slices with Cycler.getitem

My code bellow

import matplotlib as mpl
import matplotlib.pyplot as plt


colors = mpl.rcParams['axes.prop_cycle']

def make_autos_price_plot(figure, gs = None, pddata = None, axes = None):
    if not axes:
        axes = figure.add_subplot(gs[0, 0])
    min_data = pddata.groupby("make", sort=True)["price"].min()
    max_data = pddata.groupby("make", sort=True)["price"].max()
    mean_data = pddata.groupby("make", sort=True)["price"].mean()
    make_ids = geradados.get_make_ids(pddata)
    axes.set_title("Auto Price Ranges", fontsize=20)
    axes.plot(make_ids, min_data, c=colors[2], linewidth=4, alpha=0.7)
    axes.plot(make_ids, mean_data, c=colors[3], linewidth=4, alpha=0.7)
    axes.plot(make_ids, max_data, c=colors[4], linewidth=4, alpha=0.7)
    axes.set_xticks(range(-1, 14))
    axes.set_xticklabels([" "] + geradados.get_make_labels(pddata))
    axes.set_xlabel("Make", fontsize=16)
    axes.set_ylabel("Price", fontsize=16)
    high_patch = mpl.patches.Patch(color=colors[4], alpha=0.7, label="High")
    mean_patch = mpl.patches.Patch(color=colors[3], alpha=0.7, label="Mean")
    low_patch = mpl.patches.Patch(color=colors[2], alpha=0.7, label="Low")
    axes.legend(handles=[high_patch, mean_patch, low_patch], loc=2)
    if gs:
        gs.tight_layout(figure)
    return axes

Cycler doesn't cycle

This issue falls mainly along the lines of semantics. I would expect something called Cycler to do the cycling itself, instead it just represents a list, of course we want to create a cycle object from the list, but nothing in "Cycler" actually promotes this...

Perhaps naming this CycleHelper would help, and ooh, just had an idea to combine this with my own cycling experiments... one moment while I make a PR... ๐Ÿ˜ˆ.

DOC: Minor typo in `Mutiplication` section

I didn't find any function called prod() in itertools, so I assume that itertools.prod() in the documentation (section "Multiplication") refers in reality to itertools.product().

Besides is "outer product" the correct name for this product? In itertools.product() docstring, the name "Cartesian product" is used and Wikipedia doesn't seem to give the exact same definition for the two products (see Cartesian vs outer).

ENH: expand call signature of cycler()

In the discussions going on over in matplotlib/matplotlib#4686, some have asked for the cycler() call signature to be expanded a bit. Now, this can be a rabbit hole, so I will break out the proposal into stages so that we can decide just how deep we want to go:

Current signature (I call this the simple positional):
cycler(key, vals)

  1. Allow a single kwarg to be equivalent to the current notation:
    cycler(k=vals)
    Example:
    cycler(color='rgb') vs.
    cycler('color', 'rgb')

  2. Allow for multiple kwargs (all assumed to be "added" together):
    cycler(k1=v1[, k2=v2, ...])
    Example:
    cycler(color='rgb', lw=[1, 2, 3]) vs.
    cycler('color', 'rgb') + cycler('lw', [1, 2, 3])

  3. Allow for multiple positional args (all assumed to be "multiplied" together):
    cycler(k1, v1[, k2, v2, ...])
    Example:
    cycler('color', 'rgb', 'lw', [1, 2, 3])
    cycler('color', 'rgb') * cycler('lw', [1, 2, 3])

For 2 & 3, I would completely disallow the mixing of positional and keyword arguments.
If we want to avoid having two different operations possible from a single cycler(), we could forgo option 3, and go for the following:
3alt) Allow for both positional and kwargs, but assume all to be "added" together:
cycler(k1, v1[, *args][, k3=v3, **kwargs])

Whichever option (if any) people want, I can put together a PR that implements that. Ideally, I would like to have cycler.cycler() to have very similar, if not identical, call signatures to my validating version that I am making in the matplotlib PR referenced above.

Persistent (or "memory", "label") cycler

When the original proposal for the Cycler was made I put together an implementation of a "persistent cycler" that used the same back-end but provided an interface whereby values were provided in exchange for a key (label). The first time a value is requested the next value in the cycler is returned while on subsequent calls the same result will be returned for the same key.

The use case was for consistent labeling of plots throughout an analysis. When performing initial analysis it's often not important what the styles used are, but it is helpful if they stay the same.

I imagine implementing this as a subclass of Cycler with a .get() accessor (similar to a dictionary) or perhaps as a simple class that contains a cycler object within. This might put it out of scope of this project. It would be nice (long term) to be able to pass these cyclers into matplotlib functions and have styles assigned automatically (and in the case of the persistent cycler on the basis of labels).

If this seems reasonable I can open a couple of PRs with alternate implementations for discussion.

Python 3.10 compatibility

On Python 3.10.8 setup.py incorrectly raises
ERROR: Ignored the following versions that require a different python version: 0.7 Requires-Python >=3.6, <3.7; 0.8 Requires-Python >=3.6, <3.7
ERROR: Could not find a version that satisfies the requirement dataclasses==0.7 (from versions: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
ERROR: No matching distribution found for dataclasses==0.7

instead of
python_requires='>=3.6',

please consider to change with compare version as number rather than strings

Ability to update 1 or more parts of a cycler?

Don't know how feasible this would be, but I am thinking of a case where there is an existing cycler object (possibly a default cycler), and the user needs to swap out a component of the composed cycler, such as changing the color cycle.

One possible stumbling block might be if the object is in the middle of being cycled?

Ability to change the keys?

While I totally agree that we should not be able to change the values associated with each key, what about being able to change out the key names? A use case would be for normalizing property names:

>>> c = cycler('color', 'rgb') + cycler('lw', [1, 2, 3])
>>> c.key_change('lw', 'linewidth')
cycler('color', ['r', 'g', 'b']) + cycler('linewidth', [1, 2, 3])

New 0.11.0 Isn't compatible with older Matplotlib that runs on Python2.7

When running version 0.11.0 with Matplotlib 2.x.x on Python 2.7 get following error because of the f string usage.
https://pypi.org/project/cycler/0.11.0/

Basically just have to make sure if installing Matplotlib 2.x.x on Python 2.7 to force install 0.10.0

pip install cycler==0.10.0
Traceback (most recent call last):
 File "/usr/local/bin/pynmonanalyzer", line 26, in <module>
  import pyNmonPlotter
 File "/opt/rh/python27/root/usr/lib/python2.7/site-packages/pynmonanalyzer/pyNmonPlotter.py", line 24, in <module>
  import matplotlib as mpl
 File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/matplotlib/__init__.py", line 124, in <module>
  from matplotlib.rcsetup import (defaultParams,
 File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/matplotlib/rcsetup.py", line 37, in <module>
  from cycler import Cycler, cycler as ccycler
 File "/opt/rh/python27/root/usr/lib/python2.7/site-packages/cycler.py", line 260
  f"not {len(self)} and {len(other)}")
  ^
SyntaxError: invalid syntax

[feature-request] addition of cyclers requires them to be equal length

I often need to combine cyclers of unequal length. I had been under the impression that the salient feature distinguishing the '*' and '+' operations was whether or not the cyclers being joined were of equal length, but after submitting matplotlib/cycler #50, it seems that '*' is intended to combine them in a hierarchical fashion, where '+' yields simultaneous cycling.

Currently, '+' does not support unequal-length cyclers, leaving the user to solve the problem of finding the LCM of the two cyclers and extending their length appropriately. Though not insurmountable, it's a significant distraction from other work.

Thoughts?

from matplotlib.pyplot import cycler

prop_orders = {
    'color': ['k', 'r', 'g', 'b', 'c', 'm', 'y'],
    'marker': ['.', 'o', 'v', 's', '*'],
}

a=cycler('color', prop_orders['color'])
b=cycler('marker', prop_orders['marker'])

c = (a*b)()

print(next(c))
print(next(c))

Actual outcome

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "", line 242, in __add__
    "not {0} and {1}".format(len(self), len(other)))
ValueError: Can only add equal length cycles, not 7 and 5

Desired outcome
I would hope for the operation to succeed and for both attributes to be actively cycling, i.e.

{'color': 'k', 'marker': '.'}
{'color': 'r', 'marker': 'o'}

cycler interrogation

As it stands, one can not easily perform validation on the cycler components, such as validating the list of colors, and then the list of line styles. You have to iterate the cycler, and validate the individual values as scalars instead of as a whole list.

Allow getitem from a cycler

It would be useful to add __getitem__ functionality to cycler.

The use case is a "crowded" for loop where you want to get the cycler style without using a loop variable. Something like:

data_cycler = cycler('alpha', (0.2, 0.4, 0.6)) + cycler('color', ('r', 'g', 'b'))
fit_cycler = cycler('color', ('k', 'm', 'orange'))

for i, (data, fit) in enumerate(zip(data_list, fit_list)):
    ...
    plt.plot('x', 'y', data=data, data_cycler[i])
    plt.plot('x', 'y', data=data, fit_cycler[i])
    ...

In this case the index i is computed anyway, so using it for the cyclers would be handy, instead of adding the cycler inside zip().

Ideally mycycler[i] should return the item with index i % len(mycycler).

I haven't looked at the code yet. Would this be possible? Would a PR be welcome?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.