【问题标题】:Animating quiver in matplotlibmatplotlib 中的动画颤动
【发布时间】:2015-08-16 19:45:45
【问题描述】:

我遵循了一些建议的代码来回答这个问题,Plotting animated quivers in Python,但我发现我有一个没有解决的问题。考虑以下代码:

from matplotlib import pyplot as plt
import numpy as np
import matplotlib.animation as animation

def ufield(x,y,t):
    return np.cos(x+y)*np.sin(t)

def vfield(x,y,t):
    return np.sin(x+y)*np.cos(t)

x = np.linspace(0,10, num=11)
y = np.linspace(0,10, num=11)
X,Y = np.meshgrid(x,y)
t = np.linspace(0,1)

def update_quiver(j, ax, fig):
    u = ufield(X,Y,t[j])
    v = vfield(X,Y,t[j])
    Q.set_UVC(u, v)
    ax.set_title('$t$ = '+ str(t[j]))
    return Q,

fig =plt.figure()
ax = fig.gca()
u = ufield(X,Y,t[0])
v = vfield(X,Y,t[0])
Q = ax.quiver(X, Y, u, v)
ax.set_title('$t$ = '+ str(t[0]))
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')

ani = animation.FuncAnimation(fig, update_quiver, 
                              frames = range(0,t.size),
                              interval=1,fargs=(ax, fig))
plt.show()

这段代码运行良好,没有问题。但是,如果我想使用 init_func,并且我这样做了,因为我想对我的动画做更多的事情,我尝试了:

def init_quiver():
    u = ufield(X,Y,t[0])
    v = vfield(X,Y,t[0])
    Q = ax.quiver(X, Y, u, v)
    ax.set_title('$t$ = '+ str(t[0]))
    ax.set_xlabel('$x$')
    ax.set_ylabel('$y$')
    return  Q,

从脚本主体中删除这些行

u = ufield(X,Y,t[0]) 
v = vfield(X,Y,t[0]) 
Q = ax.quiver(X, Y, u, v)

并更新动画线如下:

ani = animation.FuncAnimation(fig, update_quiver, 
                              frames = range(0,t.size),
                              init_func=init_quiver,
                              interval=1,fargs=(ax, fig))
plt.show()

但是当我运行它时,我看到了第一帧,并且没有任何更新。

【问题讨论】:

    标签: python animation matplotlib


    【解决方案1】:

    当我运行你的脚本时,我看到了你描述的行为,并且在我运行它的终端中,我收到了一个带有 Traceback 结尾的错误:

     File "quiv.py", line 21, in update_quiver
    Q.set_UVC(u, v)
    NameError: global name 'Q' is not defined
    

    您可以通过添加该行来纠正此问题

    global Q 
    

    作为init_quiver 函数的第一行。

    现在完整的代码如下:

    from matplotlib import pyplot as plt
    import numpy as np
    import matplotlib.animation as animation
    
    def ufield(x,y,t):
        return np.cos(x+y)*np.sin(t)
    
    def vfield(x,y,t):
        return np.sin(x+y)*np.cos(t)
    
    x = np.linspace(0,10, num=11)
    y = np.linspace(0,10, num=11)
    X,Y = np.meshgrid(x,y)
    t = np.linspace(0,1)
    
    def update_quiver(j, ax, fig):
        u = ufield(X,Y,t[j])
        v = vfield(X,Y,t[j])
        Q.set_UVC(u, v)
        ax.set_title('$t$ = '+ str(t[j]))
        return Q,
    
    def init_quiver():
        global Q
        u = ufield(X,Y,t[0])
        v = vfield(X,Y,t[0])
        Q = ax.quiver(X, Y, u, v)
        ax.set_title('$t$ = '+ str(t[0]))
        ax.set_xlabel('$x$')
        ax.set_ylabel('$y$')
        return  Q,
    
    fig =plt.figure()
    ax = fig.gca()
    ax.set_title('$t$ = '+ str(t[0]))
    ax.set_xlabel('$x$')
    ax.set_ylabel('$y$')
    
    ani = animation.FuncAnimation(fig, update_quiver, 
                                  frames = range(0,t.size),
                                  init_func=init_quiver,
                                  interval=1,fargs=(ax, fig))
    plt.show()
    

    【讨论】:

    • 那行得通,除了,很抱歉这在原始帖子中不清楚,如果我使用 init_func,那么我不会有以下行:u = ufield(X,Y,t[ 0]) v = vfield(X,Y,t[0]) Q = ax.quiver(X, Y, u, v) 在脚本主体中。
    • 啊,我明白了。在这种情况下,您可能有范围界定问题。您是否看到类似“NameError: global name 'Q' is not defined”的错误?
    • 接下来我的建议取决于您对严格控制范围的困扰程度。如果您不太介意 - 只需将第一行 global Q 添加到您的 init_quiver 函数中。
    • 如果可行并且这是您想要做的 - 请告诉我,我将更新答案中的代码以从主体中删除 uvQ代码并将该行添加到 init func
    • 编辑问题和答案以适应 cmets 中提供的新信息。让我知道它是否有效 - 在 cmets 或通过投票/接受 :)
    猜你喜欢
    • 2019-01-15
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 2019-08-12
    • 2021-01-09
    • 1970-01-01
    相关资源
    最近更新 更多