Chester VonWinchester Chester VonWinchester - 1 month ago 12
Python Question

Matplotlib pause, hold last iteration

I have an animation loop in matplotlib, and I would like to freeze the last iteration of the animation. I am using the

pause
function with a conditional to check for the last iteration. However, in the last iteration, the previous frame is shown -- not the last frame.

Here is an example:

import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1,1)
x = np.linspace(0, 6.28, 401)

freqs = np.arange(5)

for f in freqs:
print f

ax.plot(x, np.sin(f*x))
ax.set_title('$\sin(%d x)$'%f)

if f < freqs[-1]:
plt.pause(1)
ax.cla()
else:
print "hi"
plt.show() # Fails: shows frame with `f==3`.


This prints:

0
1
2
3
4
hi


However, the last frame (with
f==4
) is never shown. The animation freezes with title, "sin(3x)", and corresponding plot data for
f==3
, not 4.

Is there a "proper" way to hold the last frame? For example,
plt.pause(10000)
would work, but seems like a hack.

Answer

I always find it much more intuitive to set up the plot first, draw it and then start the animation.

import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1,1)
x = np.linspace(0, 6.28, 401)
freqs = np.arange(5)
line, = ax.plot([],[])
ax.set_xlim([x[0], x[-1]])   
ax.set_ylim([-1, 1])   
ax.set_title('$\sin(x)$')
fig.canvas.draw() 

for f in freqs:
    print f

    line.set_data(x, np.sin(f*x))   
    ax.set_title('$\sin(%d x)$'%f)
    fig.canvas.draw()

    if f < freqs[-1]:
        plt.pause(1)
    else:
        print "hi"
plt.show()