有没有一种方法可以在matplotlib中动画化图形,而不必使用内置的动画函数?我发现它们非常笨拙难用,只需绘制一个点、清除图形,然后绘制下一个点会更简单。
我设想的是:
def f():
# do stuff here
return x, y, t
每个t
代表一个不同的帧。
我的意思是,我尝试过使用plt.clf()
、plt.close()
等方法,但似乎都没有用。
有没有一种方法可以在matplotlib中动画化图形,而不必使用内置的动画函数?我发现它们非常笨拙难用,只需绘制一个点、清除图形,然后绘制下一个点会更简单。
我设想的是:
def f():
# do stuff here
return x, y, t
每个t
代表一个不同的帧。
我的意思是,我尝试过使用plt.clf()
、plt.close()
等方法,但似乎都没有用。
没有使用 FuncAnimation
也能实现动画效果。然而,“预想的函数”的目的并不是很清晰。在动画中,时间是独立变量,即每个时间步长你会产生一些新的数据来绘制或者做类似的操作。因此,函数需要将 t
作为一个输入,并返回一些数据。
import matplotlib.pyplot as plt
import numpy as np
def f(t):
x=np.random.rand(1)
y=np.random.rand(1)
return x,y
fig, ax = plt.subplots()
ax.set_xlim(0,1)
ax.set_ylim(0,1)
for t in range(100):
x,y = f(t)
# optionally clear axes and reset limits
#plt.gca().cla()
#ax.set_xlim(0,1)
#ax.set_ylim(0,1)
ax.plot(x, y, marker="s")
ax.set_title(str(t))
fig.canvas.draw()
plt.pause(0.1)
plt.show()
FuncAnimation
。可以使用以下方式使用 FuncAnimation
来生成与上述相同的动画:import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np
def f(t):
x=np.random.rand(1)
y=np.random.rand(1)
return x,y
fig, ax = plt.subplots()
ax.set_xlim(0,1)
ax.set_ylim(0,1)
def update(t):
x,y = f(t)
# optionally clear axes and reset limits
#plt.gca().cla()
#ax.set_xlim(0,1)
#ax.set_ylim(0,1)
ax.plot(x, y, marker="s")
ax.set_title(str(t))
ani = matplotlib.animation.FuncAnimation(fig, update, frames=100)
plt.show()
这里没有太多变化,你有相同数量的行,没有什么真正尴尬的地方。
此外,当动画变得更加复杂、想要重复动画、使用blitting或者将其导出到文件时,你可以获得FuncAnimation
的所有好处。
update
中使用ax.voxels()
,但是我遇到了一个RuntimeError: The animation function must return a sequence of Artist objects.
我想知道为什么您的代码可以正常工作,即使update
没有返回任何内容。 - crypdickblit=True
,则需要返回可更新的图形对象列表。如果您使用默认值 blit=False
,则不需要该列表。 - ImportanceOfBeingErnest不清楚您为什么要避免使用
FuncAnimation
。
对于非常简单的测试,当您想要检查循环中深层次的情况时,设置一个 animation
函数并不容易。
例如,我想可视化这个奇怪的排序算法是如何运作的:https://arxiv.org/pdf/2110.01111.pdf。在我看来,最简单的方法是:
import numpy as np
import matplotlib.pyplot as plt
def sort(table):
n = len(table)
for i in range (n):
for j in range (n):
if table[i] < table[j]:
tmp = table[i]
table[i] = table[j]
table[j] = tmp
plt.plot(table, 'ro')
plt.title(f"i {i} j {j}")
plt.pause(0.001)
plt.clf() # clear figure
return table
n = 50
table = np.random.randint(1,101,n)
sort(table)
```python
我同意FuncAnimation使用起来很麻烦(完全不符合Python风格)。实际上,我认为这个函数没有太多意义。有什么优势呢?
是的,它引入了一个隐式循环,你不需要自己编写。但读者无法完全控制这个循环,除非他事先知道函数的语法,否则他甚至无法理解它。出于清晰和多功能性的原因,我个人避免使用FuncAnimation。以下是一个最小的伪代码示例:
fig=plt.figure("animation")
M=zeros((sizeX,sizeY)) # initialize the data (your image)
im=plt.imshow(M) # make an initial plot
########### RUN THE "ANIMATION" ###########################
while {some condition}:
M=yourfunction() # updates your image
im.set_array(M) # prepare the new image
fig.canvas.draw() # draw the image
plt.pause(0.1) # slow down the "animation"