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

使用欧拉法绘制单摆动画时遇FuncAnimation属性错误:无_resize_id属性

问题:使用欧拉法绘制单摆动画时触发AttributeError: FuncAnimation对象无‘_resize_id’属性

我尝试在Python中使用欧拉法,结合给定的θ值与公式绘制单摆动画,但运行时触发AttributeError,提示FuncAnimation对象不存在‘_resize_id’属性,请问问题出在哪里?

原代码

# Liður 2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def ydot(t, y):
    g = 9.81
    l = 1
    z1 = y[1]
    z2 = -g/l*np.sin(y[0])
    return np.array([z1, z2])

def eulerstep(t, x, h):
    return ([x[j]+h*ydot(t,x)[j] for j in range(len(x))])

def eulersmethod(Theta0, T, n):
    z = Theta0
    h = T/n
    t = [i*h for i in range(n)]
    theta = [[],[]]
    for i in range(n):
        z = eulerstep(t[i], z, h)
        theta[0].append(z[0])
        theta[1].append(z[1])
    return(t, theta[0], theta[1])

def animate_pendulum(x, y, h):
    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(autoscale_on = False, xlim=(-2.2, 2.2), ylim = (-2.2, 2.2))
    ax.grid()
    line = ax.plot([],[], 'o', c='blue', lw=1)
    time_text = ax.text(0.05, 0.9, '', transform = ax.transAxes)

    def animate(i):
        xline = [0, x[1]]
        yline = [0, y[1]]

        line.set_data(xline, yline)
        time_text.set_text(f"time = {i*h:1f}s")
        return line, time_text
    ani = FuncAnimation(
        fig, animate, len(x), interval = h*1000, blit = True, repeat = False
    )
    plt.show()

def min():
    L=2
    T=20
    n=500
    h=T/n
    y_0 = [np.pi/12, 0]

    t, angle, velocity = eulersmethod(y_0, T, n)
    x, y = L*np.sin(angle[:]), -L*np.cos(angle[:])
    animate_pendulum(x, y, h)

min()

问题原因及修复方案

1. line对象类型错误

ax.plot()返回的是包含单个Line2D对象的列表,原代码直接将这个列表赋值给line,后续调用line.set_data()时会因为对象类型不匹配,导致动画初始化失败,进而触发_resize_id相关的AttributeError。

修复:用逗号解包拿到单个Line2D对象:

line, = ax.plot([],[], 'o', c='blue', lw=1)

2. 动画帧更新逻辑错误

原animate(i)函数中,xline和yline固定取x[1]和y[1],导致所有帧都显示同一个位置,动画无法正常播放,同时也可能加剧动画初始化时的异常。

修复:根据帧索引i获取对应位置的坐标:

xline = [0, x[i]]
yline = [0, y[i]]

3. 函数命名冲突

原代码中函数名min()与Python内置函数min重名,可能引发潜在的命名冲突问题。

修复:将函数名改为main(),避免冲突。

修正后的完整代码

# Liður 2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def ydot(t, y):
    g = 9.81
    l = 1
    z1 = y[1]
    z2 = -g/l*np.sin(y[0])
    return np.array([z1, z2])

def eulerstep(t, x, h):
    return ([x[j]+h*ydot(t,x)[j] for j in range(len(x))])

def eulersmethod(Theta0, T, n):
    z = Theta0
    h = T/n
    t = [i*h for i in range(n)]
    theta = [[],[]]
    for i in range(n):
        z = eulerstep(t[i], z, h)
        theta[0].append(z[0])
        theta[1].append(z[1])
    return(t, theta[0], theta[1])

def animate_pendulum(x, y, h):
    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(autoscale_on = False, xlim=(-2.2, 2.2), ylim = (-2.2, 2.2))
    ax.grid()
    # 修正:解包获取单个Line2D对象
    line, = ax.plot([],[], 'o', c='blue', lw=1)
    time_text = ax.text(0.05, 0.9, '', transform = ax.transAxes)

    def animate(i):
        # 修正:根据帧索引i获取对应坐标
        xline = [0, x[i]]
        yline = [0, y[i]]

        line.set_data(xline, yline)
        time_text.set_text(f"time = {i*h:.1f}s")
        return line, time_text
    ani = FuncAnimation(
        fig, animate, frames=len(x), interval = h*1000, blit = True, repeat = False
    )
    plt.show()

def main():
    L=2
    T=20
    n=500
    h=T/n
    y_0 = [np.pi/12, 0]

    t, angle, velocity = eulersmethod(y_0, T, n)
    x, y = L*np.sin(angle[:]), -L*np.cos(angle[:])
    animate_pendulum(x, y, h)

main()

内容的提问来源于stack exchange,提问作者Óli Jón Ólason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:50:26