matplotlib/matplotlib · error · ValueError

{s!r} does not look like a color arg

Error message

{s!r} does not look like a color arg

What it means

Raised by _validate_color_or_linecolor(), the validator for the legend.labelcolor rcParam family. It accepts the special keyword 'linecolor' (match the line color) or anything validate_color accepts: named colors, 6/8-digit hex with or without the leading '#', 'none', and RGB(A) tuples. Anything else, including misspelled color names or keywords like 'edge', is rejected with 'does not look like a color arg'.

Source

Thrown at lib/matplotlib/rcsetup.py:372

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 None
    elif is_color_like(s):
        return s

    raise ValueError(f'{s!r} does not look like a color arg')


def validate_color(s):
    """Return a valid color arg."""
    if isinstance(s, str):
        if s.lower() == 'none':
            return 'none'
        if len(s) == 6 or len(s) == 8:
            stmp = '#' + s
            if is_color_like(stmp):
                return stmp

    if is_color_like(s):
        return s

    # If it is still valid, it must be a tuple (as a string from matplotlibrc).
    try:
        color = ast.literal_eval(s)

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Use a name from matplotlib.colors.get_named_colors_mapping() ('gray', 'tab:red', 'C2' are all fine here)
  2. Use full 6- or 8-digit hex ('#ff0000' or 'ff0000')
  3. Use the intended keyword 'linecolor' if you wanted the legend text to match line colors

Example fix

# before
plt.rcParams['legend.labelcolor'] = 'grey'  # not a named color

# after
plt.rcParams['legend.labelcolor'] = 'gray'
Defensive patterns

Strategy: validation

Validate before calling

from matplotlib.colors import is_color_like

def valid_labelcolor(s):
    return s == 'linecolor' or is_color_like(s)

assert valid_labelcolor('linecolor')
assert not valid_labelcolor('edge')

Type guard

from matplotlib.colors import is_color_like

def is_labelcolor(s) -> bool:
    return isinstance(s, str) and (s == 'linecolor' or is_color_like(s))

Try / catch

try:
    mpl.rcParams['legend.labelcolor'] = value
except ValueError:
    mpl.rcParams['legend.labelcolor'] = 'linecolor'  # safe default
    warnings.warn(f'ignoring invalid legend.labelcolor {value!r}')

Prevention

When it happens

Trigger: Setting plt.rcParams['legend.labelcolor'] to a misspelled name ('grey' instead of 'gray'), a keyword from a different rcParam ('edge', which belongs to patch edgecolor), or a malformed hex string such as 'ff0' (3 digits).

Common situations: Using the British spelling 'grey' (matplotlib only ships 'gray'); copying the value of another rcParam like patch.edgecolor='edge' into legend.labelcolor; truncating hex colors in template-rendered config files.

Related errors


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