Reputation: 445
I tried using matplotlib's ArtistAnimation. The text and titles of the figure are supposed to change in each frame, but they don't. I have read tons of posts on similar problems, but I still don't understand what is the solution. The demos don't show updating titles as far as I could find.
If anybody out there knows, I would be grateful!
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
fig =plt.figure()
ims=[]
for iternum in range(4):
plt.title(iternum)
plt.text(iternum,iternum,iternum)
ims.append([plt.scatter(np.random.randint(0,10,5), np.random.randint(0,20,5),marker='+' )])
#plt.cla()
ani = animation.ArtistAnimation(fig, ims, interval=500, blit=False,
repeat_delay=2000)
plt.show()
Upvotes: 9
Views: 10288
Reputation: 261
Suppose you draw a line and get a Line2D
object. Then you use Line2D.set_data
to update the line. The data (and thus the position of the line) is changing while the object is the same one, so when you do ArtistAnimation
, different frames will show the same object, which contains the most updated information.
Now come to the title. The documentation says that
Set one of the three available Axes titles. The available titles are positioned above the Axes in the center, flush with the left edge, and flush with the right edge.
and the source code is
titles = {'left': self._left_title,
'center': self.title,
'right': self._right_title}
title = _api.check_getitem(titles, loc=loc.lower())
It is the same situation. The Title
object is pre-constructed and only its content (instead of the object) is updated. When you do ArtistAnimation
, only the last update works.
To avoid this, as @Diziet Asahi and @ImportanceOfBeingErnest suggested, using Text
or FuncAnimation
.
Upvotes: 0
Reputation: 40697
To animate artists, you have to return a reference to each artists in your ims[]
array, including the Text
objects.
However it doesn't work for the title, I don't know why. Maybe somebody with a better understanding of the mechanisms involved will be able to enlighten us.
Nevertheless, the title is just a Text
object, so we can produce the desired effect using:
fig = plt.figure()
ax = fig.add_subplot(111)
ims=[]
for iternum in range(4):
ttl = plt.text(0.5, 1.01, iternum, horizontalalignment='center', verticalalignment='bottom', transform=ax.transAxes)
txt = plt.text(iternum,iternum,iternum)
ims.append([plt.scatter(np.random.randint(0,10,5), np.random.randint(0,20,5),marker='+' ), ttl, txt])
#plt.cla()
ani = animation.ArtistAnimation(fig, ims, interval=500, blit=False,
repeat_delay=2000)
Upvotes: 13
Reputation: 339230
You need to supply the artists to animate as a list of sequences to the ArtistAnimation
. In the code from the question you only supply the scatter, but not the text and title.
Unfortunately the title is also part of the axes and thus will not change even if supplied. So you may use a normal text instead.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
fig, ax = plt.subplots()
ims=[]
for iternum in range(4):
title = plt.text(0.5,1.01,iternum, ha="center",va="bottom",color=np.random.rand(3),
transform=ax.transAxes, fontsize="large")
text = ax.text(iternum,iternum,iternum)
scatter = ax.scatter(np.random.randint(0,10,5), np.random.randint(0,20,5),marker='+')
ims.append([text,scatter,title,])
ani = animation.ArtistAnimation(fig, ims, interval=500, blit=False,
repeat_delay=2000)
plt.show()
You may consider using FuncAnimation
instead of ArtistAnimation
. This would allow to change the title easily.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
fig, ax = plt.subplots()
ims=[]
text = ax.text(0,0,0)
scatter = ax.scatter(np.random.randint(0,10,5), np.random.randint(0,20,5),marker='+')
def update(iternum):
plt.title(iternum)
text.set_position((iternum, iternum))
text.set_text(str(iternum))
scatter.set_offsets(np.random.randint(0,10,(5,2)))
ani = animation.FuncAnimation(fig, update, frames=4, interval=500, blit=False,
repeat_delay=2000)
plt.show()
Upvotes: 7