Cycler
Composable style-cycle library for combining and iterating property values, best known as matplotlib's plot-styling engine
Repository Health
Technical Analysis
Cycler is a small Python library for building composable “style cycles”: iterables of dictionaries that pair property names (like color or linestyle) with a sequence of values to rotate through. Individual Cycler objects can be combined with + (zip together, matching position) or * (outer product, all combinations), letting you build rich, declarative styling rules out of simple building blocks.
Cycler was extracted from matplotlib, which uses it internally to drive axes.prop_cycle — the mechanism that decides which color and line style each new plotted line gets. It has no plotting-specific code itself, though, and is a general-purpose tool for any scenario where you need to cycle through combinations of keyword-argument-like values.
What You Get
- A
cycler(key=values)constructor that builds aCyclerobject yielding{key: value}dictionaries, one per item invalues - Composition operators:
+(zip-style, position-matched concatenation of keys) and*(outer product across all combinations of keys) - A
concat()helper for chaining two cyclers end-to-end (likeitertools.chain) rather than combining their keys - Full typing support (
py.typed) with genericCycler[K, V]type parameters for key and value types - Direct integration with matplotlib’s
axes.prop_cyclercParam, which is itself aCyclerinstance
Common Use Cases
- Customizing matplotlib’s default color/linestyle/marker rotation so successive plotted lines follow a specific styling scheme
- Building combinatorial parameter sweeps for plots (e.g. every color paired with every linestyle) using the
*operator - Any general iteration task that needs to cycle through structured combinations of keyword-style property values, outside of plotting
- Concatenating two independently-defined style cycles into one longer cycle with
concat()
Under The Hood
Architecture - The library is a single module (cycler/__init__.py, ~580 lines) centered on the Cycler class, which stores an internal list of (keys, iterable-of-values) pairs; __add__ zips two cyclers’ dictionaries together key-by-key (requiring equal length and non-overlapping keys), __mul__ takes their itertools.product() across all value combinations, and __iter__ lazily yields merged dictionaries by walking the stored structure — there is no eager materialization of the full cycle. Tech Stack - Pure Python 3.8+ with zero runtime dependencies, using only itertools, functools, operator, and typing from the standard library; built with a standard pyproject.toml/setuptools-based packaging setup. Code Quality - test_cycler.py (364 lines) exercises composition (+, *), concatenation, equality, repr, indexing, and error cases (overlapping keys, mismatched lengths) with pytest; the module is fully type-annotated using Generic[K, V] and ships py.typed for downstream type checking. API Design - The API purposefully mirrors familiar Python operators (+, *, iteration, indexing, len()) so that composing style cycles reads like ordinary arithmetic on iterables, and the single cycler() factory function covers the common case (cycler(color=[...]), cycler(key, values)) without requiring users to touch the Cycler class directly.
Used by 3 apps in this directory
argilla
AI Development · Data Engineering
Collaborate on high-quality AI training data with a self-hosted annotation platform built for LLMs, NLP, and multimodal models.
Memgraph
Databases · AI Development
High-performance in-memory graph database for AI context and real-time analytics
TDengine
Databases
A high-performance, open-source time-series database built in C for IoT, connected vehicles, and industrial monitoring workloads, with built-in stream processing, caching, and data subscription.