null
null

Reputation: 111

How to automatically close the figure at the end of an animation?

I'm trying to display an basic animation using Python and Matplotlib through animation.FuncAnimation(). The animation is non-repeating and consist in a fixed (and pre-defined) amount of frames with some fixed interval beetween them. It is meant to run once.

Here's how a single random frame is supposed to look like: random frame

The animation runs fine, but the figure doesn't close automatically after calling plt.show() since it is a blocking call.

I'm aware that the method plt.show() can be made into non-blocking call by writing plt.show(block=False), but that doesn't completely solve my problem. I haven't been able to get any information here on StackOverflow and other sites regarding how the library dispose that information of this event or so, in order to allow me to call plt.close().

I'm seaching for a pythonic way of doing this, instead of my current solution which is far from good. Here's my "solution":

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# Animation settings
def animate(frame):
    grid_size = [10, 10]
    print('frame: {}'.format(frame)) # Debug: May be useful to stop
    grid = np.random.randint(low=0, high=256, size=grid_size, dtype=np.uint8)
    ax.clear()
    ax.imshow(grid, cmap='gray', vmin=0, vmax=255) # Is the range [0, 255] or [0, 255)?

INTERVAL = 100
FRAMES_NUM = 10

anim = animation.FuncAnimation(fig, animate, interval=INTERVAL, frames=FRAMES_NUM, repeat=False)

plt.show(block=False)
plt.pause(float(FRAMES_NUM*INTERVAL)/1000) # Not pythonic
plt.close(fig)
  1. Can anyone show me a pythonic way of doing this?
  2. Am I doing this all wrong?

Upvotes: 4

Views: 4288

Answers (2)

Footman_2
Footman_2

Reputation: 1

Inside your animation function use plt.close()
For example if your last frame plotted was iFrame = 9
then:

if iFrame == 9:
    plt.close()

Upvotes: 0

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339580

Maybe you want to use the animating function to decide when to close the figure.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

grid_size = [10, 10]
grid = np.random.randint(low=0, high=256, size=grid_size, dtype=np.uint8)
im = ax.imshow(grid, cmap='gray', vmin=0, vmax=255)

# Animation settings
def animate(frame):
    if frame == FRAMES_NUM:
        print(f'{frame} == {FRAMES_NUM}; closing!')
        plt.close(fig)
    else:
        print(f'frame: {frame}') # Debug: May be useful to stop
        grid = np.random.randint(low=0, high=256, size=grid_size, dtype=np.uint8)
        im.set_array(grid)

INTERVAL = 100
FRAMES_NUM = 10

anim = animation.FuncAnimation(fig, animate, interval=INTERVAL, 
                               frames=FRAMES_NUM+1, repeat=False)

plt.show()

Upvotes: 4

Related Questions