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
Bug summary
Redrawing an
imshowimage 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 bothinterpolation='none'and'nearest'.I noticed because I have an application that redraws a figure containing two
imshowartists 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
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.interp='none'interp='nearest'interp='none'interp='nearest'Expected outcome
Restore performance to how it was in 3.10.9
Additional information
I used
cProfilewhen drawing a figure containing twoimshowartists. The results from 20 draws are below:image.py:585(draw)0.256 s tottime,matplotlib._image.resample0.071 s over 80 calls,ndarray.astype420 callsimage.py:609(draw)0.561 s tottime,image.py:350(_make_image)0.403 s tottime / 0.550 s cumtime,matplotlib._image.resample0.035 s over 40 calls,ndarray.astype2720 callsOperating 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