matplotlib / cycler Goto Github PK
View Code? Open in Web Editor NEWcycler: composable cycles
Home Page: https://matplotlib.org/cycler/
License: BSD 3-Clause "New" or "Revised" License
cycler: composable cycles
Home Page: https://matplotlib.org/cycler/
License: BSD 3-Clause "New" or "Revised" License
Candidate operator is &
such that cycler('c', 'rgb') & cycler('c', 'cmyk') == cycler('c', 'rgbcmyk')
If the keys do not match exactly, raises.
On http://matplotlib.org/cycler/ there is no obvious link to the source on github or a tar download. This is the first page that I hit when Googling "matplotlib cycler" so it would be nice to point to that. Related to matplotlib/matplotlib#5449
See #5
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).
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:
Line 2 in 1c7b926
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.
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?
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.
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
It still points to 0.10.0.
This would make unit-testing so much easier!
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
print(matplotlib.get_backend())
): Qt5Agg(mini)conda installation
Are these Python versions supported?
If they are, also update the shields :)
Please include tests in the archives of releases. This makes it easier for packagers to test whether their packaged version works. Thanks!
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.
Seems like these are not run.
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
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.
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])
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?
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!
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
+ /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 ================================================================
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... ๐.
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.
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()'.
https://github.com/matplotlib/cycler/blob/master/cycler.py#L517 has a spurious space at the beginning of the error string.
Line 49 in ee4f99b
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)
Allow a single kwarg to be equivalent to the current notation:
cycler(k=vals)
Example:
cycler(color='rgb')
vs.
cycler('color', 'rgb')
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])
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.
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'}
It would be nice to be able to add cycles of differing lengths whose properties cycle independently.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.