matplotlib/matplotlib · error · ValueError

The shapes of the passed in arrays do not match

Error message

The shapes of the passed in arrays do not match

What it means

_check_consistent_shapes is Barbs' internal gate (called from Barbs.set_UVC and Barbs.set_offsets after cbook.delete_masked_points). It collects {a.shape for a in arrays} and raises ValueError('The shapes of the passed in arrays do not match') when positions (x, y), components (u, v), colors (c) and flip flags do not all end up identically shaped after masked points are dropped.

Source

Thrown at lib/matplotlib/quiver.py:496

    if X is not None:
        X = X.ravel()
        Y = Y.ravel()
        if len(X) == nc and len(Y) == nr:
            X, Y = (a.ravel() for a in np.meshgrid(X, Y))
        elif len(X) != len(Y):
            raise ValueError('X and Y must be the same size, but '
                             f'X.size is {X.size} and Y.size is {Y.size}.')
    else:
        indexgrid = np.meshgrid(np.arange(nc), np.arange(nr))
        X, Y = (np.ravel(a) for a in indexgrid)
    # Size validation for U, V, C is left to the set_UVC method.
    return X, Y, U, V, C


def _check_consistent_shapes(*arrays):
    all_shapes = {a.shape for a in arrays}
    if len(all_shapes) != 1:
        raise ValueError('The shapes of the passed in arrays do not match')


class Quiver(mcollections.PolyCollection):
    """
    Specialized PolyCollection for arrows.

    Use set_UVC to change the size, orientation, and color of the
    arrows; their locations can be set using set_offsets().

    Much of the work in this class is done in the draw()
    method so that as much information as possible is available
    about the plot.  In subsequent draw() calls, recalculation
    is limited to things that might have changed, so there
    should be no performance penalty from putting the calculations
    in the draw() method.
    """

    _PIVOT_VALS = ('tail', 'middle', 'tip')

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Make all inputs describe the same number of barbs: assert len(x) == len(y) == len(u) == len(v) (and len(c) if given)
  2. Apply the same NaN mask across fields: mask = np.isnan(u) | np.isnan(v); x, y, u, v, c = (a[~mask] for a in (x, y, u, v, c))
  3. When positions change, rebuild the Barbs artist instead of calling set_offsets with a different count

Example fix

# before
plt.barbs(x, y, u, v, c)  # c has 100 points, u/v have 120 -> ValueError

# after
keep = ~np.isnan(u) & ~np.isnan(v)
plt.barbs(x[keep], y[keep], u[keep], v[keep], c[keep])
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
keep = ~np.isnan(u) & ~np.isnan(v) & ~np.isnan(c)
x, y, u, v, c = (np.asarray(a)[keep] for a in (x, y, u, v, c))
sizes = {a.size for a in (x, y, u, v, c)}
assert len(sizes) == 1, f'arrays describe different barb counts: {sizes}'
plt.barbs(x, y, u, v, c)

Try / catch

try:
    plt.barbs(x, y, u, v, c)
except ValueError as e:
    if 'shapes of the passed in arrays' in str(e):
        n = min(len(x), len(y), len(u), len(v), len(c))
        plt.barbs(x[:n], y[:n], u[:n], v[:n], c[:n])
    else:
        raise

Prevention

When it happens

Trigger: plt.barbs(x, y, u, v, c) where c has a different number of points than x/y/u/v; using masked arrays whose masks differ across inputs so delete_masked_points removes different counts; barb.set_offsets(xy) with more or fewer positions than the stored u/v data.

Common situations: Wind-barb plots where the color array came from a differently-sized source (e.g., station metadata subset); updating barb offsets with a new station list while keeping old u/v; NaN patterns that differ between u, v, and c fields.

Related errors


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