matplotlib/matplotlib · error · ValueError
Cannot put cycle reference ({s!r}) in prop_cycler
Error message
Cannot put cycle reference ({s!r}) in prop_cycler What it means
Colors placed into the color cycle (axes.prop_cycle / the 'color' key of a cycler) must be concrete colors. Strings matching C0..C9 are cycle references that point at the cycle itself, which would be circular, so validate_color_for_prop_cycle() rejects them before the cycle is built. Any other valid color spec (named color, hex, tuple) is accepted.
Source
Thrown at lib/matplotlib/rcsetup.py:350
return validate_color(s)
def validate_color_or_auto(s):
if cbook._str_equal(s, 'auto'):
return s
return validate_color(s)
def _validate_color_or_edge(s):
if cbook._str_equal(s, 'edge'):
return s
return validate_color(s)
def validate_color_for_prop_cycle(s):
# N-th color cycle syntax can't go into the color cycle.
if isinstance(s, str) and re.match("^C[0-9]$", s):
raise ValueError(f"Cannot put cycle reference ({s!r}) in prop_cycler")
return validate_color(s)
def _validate_color_or_linecolor(s):
if cbook._str_equal(s, 'linecolor'):
return s
elif cbook._str_equal(s, 'mfc') or cbook._str_equal(s, 'markerfacecolor'):
return 'markerfacecolor'
elif cbook._str_equal(s, 'mec') or cbook._str_equal(s, 'markeredgecolor'):
return 'markeredgecolor'
elif s is None:
return None
elif isinstance(s, str) and len(s) == 6 or len(s) == 8:
stmp = '#' + s
if is_color_like(stmp):
return stmp
if s.lower() == 'none':
return NoneView on GitHub (pinned to b379c1b69e)
Solutions
- Replace each C reference with the actual palette entry it refers to, e.g. 'C0' -> 'tab:blue', 'C1' -> 'tab:orange' (the default tab10 cycle)
- Or pass explicit hex/named colors: cycler(color=['#1f77b4', '#ff7f0e'])
- Keep C0..C9 only for per-artist color= kwargs, never inside prop_cycle
Example fix
# before
from cycler import cycler
import matplotlib.pyplot as plt
plt.rc('axes', prop_cycle=cycler(color=['C0', 'C1'])) # ValueError
# after
plt.rc('axes', prop_cycle=cycler(color=['tab:blue', 'tab:orange'])) Defensive patterns
Strategy: validation
Validate before calling
import re
from matplotlib.colors import is_color_like
def valid_cycle_color(s):
return not (isinstance(s, str) and re.fullmatch(r'C[0-9]', s)) and is_color_like(s)
assert not valid_cycle_color('C1')
assert valid_cycle_color('tab:orange') Type guard
import re
from matplotlib.colors import is_color_like
def is_prop_cycle_color(s) -> bool:
return is_color_like(s) and not (isinstance(s, str) and re.fullmatch(r'C[0-9]', s)) Try / catch
from cycler import cycler
try:
plt.rc('axes', prop_cycle=cycler(color=color_list))
except ValueError as e:
color_list = [c for c in color_list if not re.fullmatch(r'C[0-9]', str(c))]
plt.rc('axes', prop_cycle=cycler(color=color_list or ['tab:blue'])) Prevention
- Reserve C0..C9 for per-artist color= kwargs only
- When templating style files, lint 'color:' lines for bare cN tokens
- Default custom cycles to explicit palette names (tab10 entries) so they survive this rule
When it happens
Trigger: Calling plt.rc('axes', prop_cycle=cycler(color=['C0', 'C1'])) or putting 'color: c0, c1' inside a style/matplotlibrc file; building a cycler from a list of artist color kwargs that legitimately used C references elsewhere.
Common situations: Copying a per-line color like plt.plot(..., color='C1') into a custom color-cycle definition for a style file or a reusable plotting helper; converting old-style 'axes.color_cycle' rcParams content that contained C references.
Related errors
- {s!r} does not look like a color arg
- 'markevery' tuple must be pair of ints or of floats
- 'markevery' list must have all elements of type int
- Object is not a string or Cycler instance: {s!r}
- 'facecolor' or 'color' argument must be a valid color or seq
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/02b3eee623b3a19d.
Report an issue: GitHub.