1

I have N=lots of 256x256 images (grayscales saved as numpy.ndarray with shape=(N, 256, 256)) and want to look at all of them by use of animation. I also want to add some label showing details related to each of the images, such as its index, its maximum value, etc. I'm using matplotlib, which I'm not familiar with.

There are a number of StackOverflow topics concerned with this exact problem (e.g. 1, 2, 4), as well as numerous tutorials (e.g. 3). I pieced together below attempts at solving the problem from these sources.

The two possibilities I have tried are using the matplotlib.animation classes FuncAnimation and ArtistAnimation. I'm not happy with my solutions because:

  1. I have not been able to display and animate text information together with the images. I can display animated text on top of the images using axes.text but don't know how to put text next to the image.

  2. I strongly dislike the FuncAnimation solution for aesthetic reasons (use of global variables, etc.)

  3. I also want an animated colorbar. I think this is possible (somehow) with FuncAnimation but I don't see how it is possible with ArtistAnimation
  4. ArtistAnimation gets slow since a large number of Artists (each picture) are required
# python 3.6
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, ArtistAnimation

images = np.random.rand(1000,256,256) 
fig, ax = plt.subplots()

# ####################### Solution using ArtistAnimation ##################################################
# for much larger numbers of pictures this gets very slow
# How do I display information about the current picture as text next to the plot?
ims = []
for i in range(images.shape[0]):
    ims.append([plt.imshow(images[i], animated=True)])

ani = ArtistAnimation(fig, ims, interval=250, blit=True, repeat_delay=5000)
plt.show()

# ####################### Solution using FuncAnimation ##################################################
# I don't like to use global variables in principle (but still want to know how to make this work).
# I can't figure out a way to display text while animating. 
# Here I try to animate title and return it from update_figure (since it's an Artist and should update?!) but it has no effect.
nof_frames = images.shape[0]
i = 0
im = plt.imshow(images[0], animated=True)
# I do know that variables that aren't changed need not be declared global.
# However, I want to mark them and don't like accessing global variables in the first place.
def update_figure(frame, *frargs):
    global i, nof_frames, ax, images, im
    if i < nof_frames - 1:
        i += 1
    else:
        i = 0
    im.set_array(images[i])
    ax.set_title(str(i)) # this has no effect

    return im, ax

ani = FuncAnimation(fig, update_figure, interval=300, blit=True)
plt.show()
Adomas Baliuka
  • 1,384
  • 2
  • 14
  • 29
  • 1
    We can't do anything about 2. (personal dislikes), and given 3. and 4., the conclusion is to use `FuncAnimation`. This leaves the only relevant problem to be how to update text outside an axes with `blit=True`. The short answer to this: it's not possible. So you either need to set `blit=False`, or you need to put the text inside the axes area where it can be blitted (and return it from the function). – ImportanceOfBeingErnest Aug 20 '19 at 01:11

0 Answers0