Skip to content

[Bug]: AxesImage redraws ~2x slower in 3.11 than in 3.10 #32240

Description

@zekebarger

Bug summary

Redrawing an imshow image is ~2x slower in 3.11.0/3.11.1 than in 3.10.9. The slowdown appears for both scalar and RGBA arrays, at both interpolation='none' and 'nearest'.

I noticed because I have an application that redraws a figure containing two imshow artists on every keypress. The app went from ~19 ms to ~40 ms per frame after the matplotlib upgrade, with no code changes.

Code for reproduction

"""Timing of AxesImage draws."""
import time
import statistics
import matplotlib
matplotlib.use("Agg")
import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(0)
W = 21600
scalar = rng.random((60, W))
rgba = rng.random((10, W, 4))


def bench(arr, interpolation, label):
    fig = plt.figure(figsize=(20, 6), dpi=100)
    ax = fig.add_subplot()
    ax.imshow(arr, aspect="auto", origin="lower", interpolation=interpolation)
    fig.canvas.draw()
    ts = []
    for _ in range(15):
        t = time.perf_counter()
        fig.canvas.draw()
        ts.append((time.perf_counter() - t) * 1000)
    plt.close(fig)
    print(f"  {label:34s} {statistics.median(ts):7.2f} ms")


print(f"matplotlib {matplotlib.__version__} | numpy {np.__version__}")
bench(scalar, "none", "scalar array, interp='none'")
bench(scalar, "nearest", "scalar array, interp='nearest'")
bench(rgba, "none", "RGBA array,   interp='none'")
bench(rgba, "nearest", "RGBA array,   interp='nearest'")

Actual outcome

This table shows the median of the 15 canvas.draw() calls for each matplotlib version. The tests were all run on the same machine, using numpy 2.4.6. I got basically the same results running the test multiple times. It seems like the meaningful change was in 3.11.0.

case 3.10.9 3.11.0 3.11.1 slowdown
scalar array, interp='none' 25.41 ms 49.27 ms 50.70 ms 2.00x
scalar array, interp='nearest' 25.97 ms 56.23 ms 55.67 ms 2.14x
RGBA array, interp='none' 13.17 ms 32.37 ms 32.21 ms 2.45x
RGBA array, interp='nearest' 13.08 ms 33.49 ms 33.26 ms 2.54x

Expected outcome

Restore performance to how it was in 3.10.9

Additional information

I used cProfile when drawing a figure containing two imshow artists. The results from 20 draws are below:

  • 3.10.9 — image.py:585(draw) 0.256 s tottime, matplotlib._image.resample 0.071 s over 80 calls, ndarray.astype 420 calls
  • 3.11.1 — image.py:609(draw) 0.561 s tottime, image.py:350(_make_image) 0.403 s tottime / 0.550 s cumtime, matplotlib._image.resample 0.035 s over 40 calls, ndarray.astype 2720 calls

Operating system

macOS 26.5.1 (arm64)

Matplotlib Version

3.11.1

Matplotlib Backend

Agg

Python version

3.13.2

Jupyter version

N/A

Installation

pip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions