You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib FuncAnimation语法错误:旋转矢量动画仅显示静态图像

问题:Matplotlib矢量旋转动画仅显示静态图像

我尝试制作一个简单的动画,展示自定义半径、随角度θ旋转的矢量及其在x、y轴的投影,但运行代码后仅得到静态图像。我的思路是在每一帧删除旧quiver并重新绘制,却无法实现动态效果。

原代码

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

fig, ax = plt.subplots(1, figsize=(15,15))

theta = np.pi/3
radius = 2

def get_vector(theta):
    vector = np.array([radius*np.cos(theta),radius*np.sin(theta)])
    vectors = np.array([vector, [vector[0], 0], [0, vector[1]]])
    return vectors

origin = np.array([[0,0,0],[0,0,0]])
quiver = ax.quiver(*origin, get_vector(theta)[:, 0], get_vector(theta)[:, 1], scale=1, scale_units='xy', angles='xy', color=['red','green','blue'])
ax.set_xlim(-radius-0.5,radius+0.5)
ax.set_ylim(-radius-0.5,radius+0.5)

def update(theta):
    global quiver
    quiver.remove()
    quiver = ax.quiver(*origin, get_vector(theta)[:, 0], get_vector(theta)[:, 1], scale=1, scale_units='xy', angles='xy', color=['red','green','blue'])

angle = np.linspace( 0 , 2 * np.pi , 150 ) 
anim = FuncAnimation(fig, update, frames=angle, interval=50)

x_size = radius * np.cos( angle ) 
y_size = radius * np.sin( angle ) 
ax.plot( x_size, y_size )

plt.grid()
plt.show()

问题排查与修复

问题核心在于两点:

  1. update函数未返回更新的绘图元素,Matplotlib无法识别需要重绘的内容
  2. 部分环境下动画对象若未被持续引用,会被垃圾回收导致无法播放

修改后的代码如下:

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

fig, ax = plt.subplots(1, figsize=(15,15))

radius = 2

def get_vector(theta):
    vector = np.array([radius*np.cos(theta),radius*np.sin(theta)])
    vectors = np.array([vector, [vector[0], 0], [0, vector[1]]])
    return vectors

origin = np.array([[0,0,0],[0,0,0]])
# 初始化起始帧矢量
quiver = ax.quiver(*origin, get_vector(0)[:, 0], get_vector(0)[:, 1], scale=1, scale_units='xy', angles='xy', color=['red','green','blue'])
ax.set_xlim(-radius-0.5,radius+0.5)
ax.set_ylim(-radius-0.5,radius+0.5)

def update(theta):
    global quiver
    quiver.remove()
    quiver = ax.quiver(*origin, get_vector(theta)[:, 0], get_vector(theta)[:, 1], scale=1, scale_units='xy', angles='xy', color=['red','green','blue'])
    # 返回更新元素,明确告知Matplotlib需要重绘的对象
    return quiver,

angle = np.linspace( 0 , 2 * np.pi , 150 ) 
# 添加blit=True优化动画流畅度
anim = FuncAnimation(fig, update, frames=angle, interval=50, blit=True)

# 绘制参考圆
x_size = radius * np.cos( angle ) 
y_size = radius * np.sin( angle ) 
ax.plot( x_size, y_size )

plt.grid()
# 若在Jupyter环境运行,需添加以下配置才能正常显示动画
# plt.rcParams['animation.html'] = 'jshtml'
plt.show()

关键修改点

  • 让update函数返回quiver,(逗号确保返回元组格式),明确标记需要重绘的元素
  • 添加blit=True参数,减少冗余重绘,提升动画流畅度
  • 初始化时使用θ=0的矢量,与动画起始帧保持一致

内容的提问来源于stack exchange,提问作者Mephistopheles Faust

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:05:21