10

I'd like to display a simple animation by calling imshow in a for loop. Here's a demo of my problem:

import pylab,time
images = [pylab.uniform(0,255,(50,50)) for _ in xrange(40)]
pylab.ion()
timings = []
for img in images:
  tic = time.time()
  pylab.imshow(img)
  pylab.draw()
  toc = time.time()
  timings.append(toc-tic)
pylab.clf()
pylab.plot(timings)
pylab.title('elapsed time per iteration')
pylab.ioff()
pylab.show()

Note that I generate the images before running the loop, and that the only parts I time are the imshow and draw functions. I'm getting results that look like this: Result of running my demo

How can I avoid this slowdown?

perimosocordiae
  • 17,287
  • 14
  • 60
  • 76

1 Answers1

19

Things are slowing down because you're adding more and more images and drawing them all each time.

Either 1) clear the plot between each image (In your case, pylab.cla()), or better yet 2) don't make a new image, just set the data of the existing image to the new data.

As an example of using cla():

import matplotlib.pyplot as plt
import numpy as np

images = np.random.uniform(0, 255, size=(40, 50, 50))

fig, ax = plt.subplots()

fig.show()
for image in images:
    ax.imshow(image)
    fig.canvas.draw()
    ax.cla()

And as an example of just setting the data:

import matplotlib.pyplot as plt
import numpy as np

images = np.random.uniform(0, 255, size=(40, 50, 50))

fig, ax = plt.subplots()

im = ax.imshow(images[0])
fig.show()
for image in images[1:]:
    im.set_data(image)
    fig.canvas.draw()

You'll notice that the second method is considerably faster.

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • `set_data()` instead of repeating `imshow()`s saved me literal hours of computing time, even though I was careful about re-using figure, axis and colorbar – YPOC Jan 19 '23 at 12:46