matplotlib/matplotlib · warning

Data with more than 2**24 rows cannot be accurately displaye

Error message

Data with more than 2**24 rows cannot be accurately displayed. Downsampling to less than 2**24 rows before displaying. To remove this warning, manually downsample your data.

What it means

The row-side twin of the column check in matplotlib's _resample helper: the AGG renderer needs coordinates to fit 24-bit signed integers, so an image array with more than 2**24 (16,777,216) rows cannot be displayed accurately. matplotlib warns and decimates the rows with an integer step (data[::step, :]) while adding a compensating Affine2D(1, step) to the transform. The column budget is lower (2**23).

Source

Thrown at lib/matplotlib/image.py:182

    """
    Convenience wrapper around `._image.resample` to resample *data* to
    *out_shape* (with a third dimension if *data* is RGBA) that takes care of
    allocating the output array and fetching the relevant properties from the
    Image object *image_obj*.
    """
    # AGG can only handle coordinates smaller than 24-bit signed integers,
    # so raise errors if the input data is larger than _image.resample can
    # handle.
    msg = ('Data with more than {n} cannot be accurately displayed. '
           'Downsampling to less than {n} before displaying. '
           'To remove this warning, manually downsample your data.')
    if data.shape[1] > 2**23:
        warnings.warn(msg.format(n='2**23 columns'))
        step = int(np.ceil(data.shape[1] / 2**23))
        data = data[:, ::step]
        transform = Affine2D().scale(step, 1) + transform
    if data.shape[0] > 2**24:
        warnings.warn(msg.format(n='2**24 rows'))
        step = int(np.ceil(data.shape[0] / 2**24))
        data = data[::step, :]
        transform = Affine2D().scale(1, step) + transform
    # decide if we need to apply anti-aliasing if the data is upsampled:
    # compare the number of displayed pixels to the number of
    # the data pixels.
    interpolation = image_obj.get_interpolation()
    if interpolation in ['antialiased', 'auto']:
        # don't antialias if upsampling by an integer number or
        # if zooming in more than a factor of 3
        pos = np.array([[0, 0], [data.shape[1], data.shape[0]]])
        disp = transform.transform(pos)
        dispx = np.abs(np.diff(disp[:, 0]))
        dispy = np.abs(np.diff(disp[:, 1]))
        if ((dispx > 3 * data.shape[1] or
                dispx == data.shape[1] or
                dispx == 2 * data.shape[1]) and
            (dispy > 3 * data.shape[0] or

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Downsample before plotting: step = int(np.ceil(A.shape[0] / 2**24)); ax.imshow(A[::step, :], extent=(0, A.shape[1], A.shape[0], 0)).
  2. Use block statistics (mean or min/max pooling over row blocks) so thin features survive the reduction.
  3. Slice to the region of interest instead of passing the full-height array to imshow.

Example fix

# before
ax.imshow(tall)               # tall.shape == (20_000_000, 500)

# after
step = int(np.ceil(tall.shape[0] / 2**24))
ax.imshow(tall[::step, :], extent=(0, tall.shape[1], tall.shape[0], 0))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def fit_agg_limits(data):
    h, w = data.shape[:2]
    if h > 2**24:
        data = data[::int(np.ceil(h / 2**24)), :]
    if w > 2**23:
        data = data[:, ::int(np.ceil(w / 2**23))]
    return data

Prevention

When it happens

Trigger: ax.imshow(A) where A.shape[0] > 2**24 - e.g. tens of millions of scan lines, a full-depth volumetric slice, or a stacked time-series raster; any draw path that routes through _resample with an extremely tall array.

Common situations: Instrument/telemetry captures with tens of millions of rows; concatenating many rasters vertically before plotting; plotting raw sensor streams without decimation.

Related errors


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