When using imshow
artist in FuncAnimation
the first frame cannot be blitted away. It will always leave the first frame untouched, but other artists behave correctly. How can we fix this?
Here is the code:
from matplotlib import pyplot as plt, animation, cm
def show_imshow_blit_bug(start=0, blit=True):
pic = np.zeros((10, 10), dtype=float)
x = np.arange(0, 2 * np.pi, 0.01)
amp = (x.max() - x.min()) / 2
fig, ax = plt.subplots()
extent = [x.min(), x.max(), -amp, amp]
_cm = cm.jet
picf = pic.flat
picf[0] = 1
picf[-1] = 0.5
imart = ax.imshow(pic,
origin='lower',
extent=extent,
cmap=_cm
)
# imart.set_animated(True) # set or not has no effect
line, = ax.plot(x, np.sin(x)*amp)
line2, = ax.plot(x[[0, -1]], np.array([-amp, amp]), 'r')
line2.set_animated(True) # this make line2 disappear, since updater does not return this artist
line3, = ax.plot(x[[0, -1]], np.array([amp, -amp]), 'C1')
#line3 will be keeped since _animated = False
ax.set_xlim(x.min(), x.max())
ax.set_ylim(-amp * 1.1, amp * 1.1)
fig.tight_layout()
def updater(fn):
print(fn)
np.random.shuffle(picf)
imart.set_data(np.ma.masked_where(pic == 0, pic))
line.set_ydata(np.sin(x + fn / 10.0)*amp)
return (imart, line,) # Both artist will be in blit list
nframe = range(start, 200)
anima = animation.FuncAnimation(fig,
updater,
nframe,
interval=20,
blit=blit,
repeat=False
)
plt.show()
I am aware there is a hack solution to set artists invisible in init_func
. But this is a hack and I do not want to use init_func
which is not compatible with the rest of codes.