matplotlib/matplotlib · error · ValueError

{s!r} is not a valid cycler construction: {e}

Error message

{s!r} is not a valid cycler construction: {e}

What it means

validate_cycler() (lib/matplotlib/rcsetup.py:927) is the rcParams validator for axes.prop_cycle. When given a string it calls _parse_cycler_string(); any exception raised while parsing or evaluating (syntax error, unsupported operator, non-cycler() call, non-literal leaf) is caught and re-raised as ValueError with this wrapper message, chaining the original cause via 'from e'.

Source

Thrown at lib/matplotlib/rcsetup.py:927

            loc = ast.literal_eval(loc)
        except (SyntaxError, ValueError):
            pass
    if isinstance(loc, int):
        if 0 <= loc <= 10:
            return loc
    if isinstance(loc, tuple):
        if len(loc) == 2 and all(isinstance(e, Real) for e in loc):
            return loc
    raise ValueError(f"{loc} is not a valid legend location.")


def validate_cycler(s):
    """Return a Cycler object from a string repr or the object itself."""
    if isinstance(s, str):
        try:
            s = _parse_cycler_string(s)
        except Exception as e:
            raise ValueError(f"{s!r} is not a valid cycler construction: {e}"
                             ) from e
    if isinstance(s, Cycler):
        cycler_inst = s
    else:
        raise ValueError(f"Object is not a string or Cycler instance: {s!r}")

    unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases))
    if unknowns:
        raise ValueError("Unknown artist properties: %s" % unknowns)

    # Not a full validation, but it'll at least normalize property names
    # A fuller validation would require v0.10 of cycler.
    checker = set()
    for prop in cycler_inst.keys:
        norm_prop = _prop_aliases.get(prop, prop)
        if norm_prop != prop and norm_prop in cycler_inst.keys:
            raise ValueError(f"Cannot specify both {norm_prop!r} and alias "
                             f"{prop!r} in the same prop_cycle")

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Read the chained cause (__cause__) — it names the exact inner problem; fix that first
  2. Simplify the string to plain cycler(...) calls with literal lists joined by +
  3. Skip strings entirely: assign the Cycler object built in code
  4. Validate style files at startup with matplotlib.style.use after a dry-run rcParams assignment so failures surface early

Example fix

# before
mpl.rcParams['axes.prop_cycle'] = "cycler(lw=[1, 2]"  # missing closing paren
# after
mpl.rcParams['axes.prop_cycle'] = "cycler(lw=[1, 2])"
Defensive patterns

Strategy: try-catch

Validate before calling

from matplotlib.rcsetup import validate_cycler
try:
    validate_cycler(prop_cycle_string)
except ValueError as e:
    raise ValueError(f'style file prop_cycle broken: {e}') from e

Type guard

def is_parseable_cycler_string(s):
    from matplotlib.rcsetup import validate_cycler
    try:
        validate_cycler(s)
        return True
    except ValueError:
        return False

Try / catch

try:
    mpl.rcParams['axes.prop_cycle'] = s
except ValueError as e:
    if 'is not a valid cycler construction' in str(e):
        mpl.rcParams['axes.prop_cycle'] = cycler(color=plt.rcParams['axes.prop_cycle'].by_key().get('color', ['b']))
    else:
        raise

Prevention

When it happens

Trigger: rcParams['axes.prop_cycle'] = 'cycler(linestyle=["-", "--"]' (unbalanced); 'cycler(color=colors)' (name not literal); 'cycler(c="rgb") - cycler(...)' (unsupported operator); any .mplstyle axes.prop_cycle line that fails any inner rule of the safe parser.

Common situations: Loading third-party or hand-edited style sheets with subtly broken cycler strings; upgrading matplotlib versions that replaced eval with the restricted parser so previously 'working' creative strings now fail; composing prop_cycle strings with f-strings.

Related errors


AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21). Data as JSON: /api/errors/592858b71b088e04. Report an issue: GitHub.