使用matplotlib进行动画制作,无需使用动画函数

4

有没有一种方法可以在matplotlib中动画化图形,而不必使用内置的动画函数?我发现它们非常笨拙难用,只需绘制一个点、清除图形,然后绘制下一个点会更简单。

我设想的是:

def f():
     # do stuff here
     return x, y, t

每个t代表一个不同的帧。

我的意思是,我尝试过使用plt.clf()plt.close()等方法,但似乎都没有用。


有一个程序相关的代码需要翻译为中文,请仅返回翻译后的文本: fig=plt.figure("animation") # 创建一张名为“animation”的图像 im=plt.imshow(M.reshape(lN,lN),interpolation='none') # 将M转化为二维数组并显示while {some condition}: # 当满足某些条件时 M=updateFunc() # 更新和改变神经元的电位 im.set_array(M) # 重设图像的值 fig.canvas.draw() # 绘制图像 plt.pause(0.1) # 减慢“动画”速度 - mchrgr2000
3个回答

4

没有使用 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没有返回任何内容。 - crypdick
1
如果您使用 blit=True,则需要返回可更新的图形对象列表。如果您使用默认值 blit=False,则不需要该列表。 - ImportanceOfBeingErnest

1

不清楚您为什么要避免使用 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


0

我同意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"

非常简单,您可以看到代码中发生的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接