matplotlib/matplotlib · error · ValueError

Input could not be cast to an at-least-1D NumPy array

Error message

Input could not be cast to an at-least-1D NumPy array

What it means

Raised by cbook.index_of, which matplotlib uses to synthesize x-coordinates when only y-data is given (e.g. ax.plot(y)). It first tries the pandas path (y.index/y.values), then _check_1d to coerce y to a 1D NumPy array; if that conversion raises (ragged nested input, object NumPy cannot coerce), the ValueError is raised as the final answer. It means the y argument is not representable as a single flat numeric array.

Source

Thrown at lib/matplotlib/cbook.py:1772

    y : float or array-like

    Returns
    -------
    x, y : ndarray
       The x and y values to plot.
    """
    try:
        return y.index.to_numpy(), y.to_numpy()
    except AttributeError:
        pass
    try:
        y = _check_1d(y)
    except (VisibleDeprecationWarning, ValueError):
        # NumPy 1.19 will warn on ragged input, and we can't actually use it.
        pass
    else:
        return np.arange(y.shape[0], dtype=float), y
    raise ValueError('Input could not be cast to an at-least-1D NumPy array')


def safe_first_element(obj):
    """
    Return the first element in *obj*.

    This is a type-independent way of obtaining the first element,
    supporting both index access and the iterator protocol.
    """
    if isinstance(obj, collections.abc.Iterator):
        # needed to accept `array.flat` as input.
        # np.flatiter reports as an instance of collections.Iterator but can still be
        # indexed via []. This has the side effect of re-setting the iterator, but
        # that is acceptable.
        try:
            return obj[0]
        except TypeError:
            pass

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Plot each variable-length series in its own ax.plot call
  2. Flatten uniform nested data with np.ravel(y) before plotting
  3. Coerce and validate explicitly first: y = np.asarray(y, dtype=float)
  4. For pandas-like objects pass x explicitly (ax.plot(df.index, df[col])) so index_of is bypassed

Example fix

# before
ax.plot([[1, 2], [3, 4, 5]])  # ragged: cannot cast to 1D

# after
for series in [[1, 2], [3, 4, 5]]:
    ax.plot(series)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def plot_ready_1d(y):
    try:
        arr = np.asarray(y)
    except (ValueError, TypeError) as e:
        return False, f'not convertible to ndarray: {e}'
    if arr.ndim < 1:
        return False, 'input is 0-dimensional'
    if arr.dtype == object:
        return False, 'object dtype (ragged?) input'
    return True, 'ok'

ok, why = plot_ready_1d(data)
if ok:
    ax.plot(data)
else:
    for series in data:  # ragged: plot series by series
        ax.plot(series)

Type guard

import numpy as np

def is_plottable_1d(y) -> bool:
    try:
        a = np.asarray(y)
    except Exception:
        return False
    return a.ndim >= 1 and a.dtype != object

Try / catch

try:
    ax.plot(data)
except ValueError as e:
    if 'could not be cast' in str(e):
        for series in data:
            ax.plot(series)  # fall back to per-series plotting
    else:
        raise

Prevention

When it happens

Trigger: ax.plot(y) / APIs that call cbook.index_of with y = [[1, 2], [3, 4, 5]] (ragged nested list), a sequence of unequal-length sequences, an object with no .index and no ndarray coercion, or heterogeneous data that NumPy >= 1.24 refuses to convert (ragged creation changed from deprecation warning to hard ValueError).

Common situations: Plotting variable-length windows/batches in one call; upgrading NumPy past 1.24 so old ragged-input deprecation warnings become this error; passing dict views or custom container objects where a flat list/ndarray was expected.

Related errors


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