首页 > 解决方案 > 动画情节“列表”对象没有属性“set_data”,即使我遵循针对其他类似问题的建议?

问题描述

让我先让大家知道我对编程还有些陌生,所以我确信我的代码在某些部分可能相当低效,并且有一些可能令人畏惧的行。我提前道歉。

无论如何,我正在尝试编写一个 2D 物理模拟器,该模拟器在给定一组初始条件的情况下模拟两个天体之间的相互作用,然后对它们的轨迹进行动画处理。问题是,当我运行我的代码时,我收到以下错误:AttributeError: 'list' object has no attribute 'set_data',特别是line.set_data([],[])init(). 这个错误指向我在下面标记的第 61 行(我删除了一些不必要的注释,并且肯定弄乱了您在下面看到的代码片段的行号)。这是我的代码:

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

# ->> Initialize Figure <<-
fig = plt.figure()                                  # creates figure window
ax = plt.axes(xlim=(x[0],x[-1]),ylim=(y[0],y[-1]))  # creates axis object
plotColors = ("blue","red","green","black") # colors to use in plots (qty. must match or exceed numBodies)
line, = ax.plot([],[],lw=2)                 # creates blank line object
lines = []                                  # list that contains line objects for simulated bodies
numBodies = 2                               # number of bodies to intitialize (not necessarily simulate)
numArgs = 2                                 # DO NOT CHANGE: number of bodies to simulate
xBody1,xBody2 = [],[]                       # tracks x-coordinates for both simulated bodies
yBody1,yBody2 = [],[]                       # tracks y-coordinates for both simulated bodies

print("-- One --")

# ->> Initialize list of line objects for all bodies <<-
for i in range(numArgs):
    line_obj = ax.plot([],[],lw=2,color=plotColors[i])
    lines.append(line_obj)

print("-- Two --")

# ->> Initialize Animation Frame Initialization Function <<-
def init():
    for line in lines:
        line.set_data([],[])  #............................................<<<<<<< LINE 61 <<<<<<<
    return lines

print("-- Three --")

# ->> Initialize Animation Function (called sequentially) <<-
def animate(i):
        
    xList = [xBody1,xBody2]     # contains x-coordinate data for each body
    yList = [yBody1,yBody2]     # contains y-coordinate data for each body
    
    for num,line in enumerate(lines):           # for index in range(0,1):
        line.set_data(xList[num],yList[num])    # set data for each line separately
    
    plt.pause(0.1)
    return lines

# ->> Initialize Numerical Calculation Sequence <<-
def calculate(lastP,lastV,lastA):               # calculates each iteration of movements
    x1 = lastP[0] + lastV[0]*dt + 0.5*lastA[0]*np.square(dt)
    y1 = lastP[1] + lastV[1]*dt + 0.5*lastA[1]*np.square(dt)
    x2 = lastP[2] + lastV[2]*dt + 0.5*lastA[2]*np.square(dt)
    y2 = lastP[3] + lastV[3]*dt + 0.5*lastA[3]*np.square(dt)
    vx1 = lastV[0] + lastA[0]*dt
    vy1 = lastV[1] + lastA[1]*dt
    vx2 = lastV[2] + lastA[2]*dt
    vy2 = lastV[3] + lastA[3]*dt
    fx1 = G*m1*m2/np.square(x2-x1)
    fy1 = G*m1*m2/np.square(y2-y1)
    fx2 = G*m1*m2/np.square(x1-x2)
    fy2 = G*m1*m2/np.square(y1-y2)
    ax1 = fx1/m1
    ay1 = fy1/m1
    ax2 = fx2/m2
    ay2 = fy2/m2
    pos = [x1,y1,x2,y2]
    vel = [vx1,vy1,vx2,vy2]
    force = [fx1,fy1,fx2,fy2]
    acc = [ax1,ay1,ax2,ay2]
    return pos,vel,force,acc

# ->> Initialize Simulation Function
def simulate(sPos,sVel,sAcc):     # handles calculations & data management for animation
    xx1,xx2 = [],[]
    yy1,yy2 = [],[]
    xx1.append(sPos[0])
    yy1.append(sPos[1])
    xx2.append(sPos[2])
    yy2.append(sPos[3])
    Pos,Vel,Force,Acc = calculate(sPos,sVel,sAcc)
    for t in range(N):
        lastPos = Pos
        lastVel = Vel
        lastAcc = Acc
        Pos,Vel,Force,Acc = calculate(lastPos,lastVel,lastAcc)
        xx1.append(Pos[0])
        yy1.append(Pos[1])
        xx2.append(Pos[2])
        yy2.append(Pos[3])
    return xx1,yy1,xx2,yy2

print("-- Four --")

# ->> Specify Simulation Quantities <<-
G = 1           # gravitational constant (actually equals 6.67430e-11)
tmin = 0
tmax = 10000
N = 20000
dt = (tmax-tmin)/N

# ->> Specify Initial Conditions <<-
m1 = 1000       # mass of body 1 (kg)
m2 = 1000       # mass of body 2 (kg)

x1s = 10        # starting x-coordinate of body 1
y1s = 90        # starting y-coordinate of body 1
x2s = 90        # starting x-coordinate of body 2
y2s = 10        # starting y-coordinate of body 2

fx1s = 0    # initial x-directed force on body 1 (N) at t=0-
fy1s = 0    # initial y-directed force on body 1 (N) at t=0-
fx2s = 0    # initial x-directed force on body 2 (N) at t=0-
fy2s = 0    # initial y-directed force on body 2 (N) at t=0-

ax1s = fx1s/m1  # initial x-acceleration of body 1 (m/s^2)
ay1s = fy1s/m1  # initial y-acceleration of body 1 (m/s^2)
ax2s = fx2s/m2  # initial x-acceleration of body 2 (m/s^2)
ay2s = fy2s/m2  # initial y-acceleration of body 2 (m/s^2)

vx1s = 0        # initial x-velocity of body 1 (m/s)
vy1s = 0        # initial y-velocity of body 1 (m/s)
vx2s = 0        # initial x-velocity of body 2 (m/s)
vy2s = 0        # initial y-velocity of body 2 (m/s)

# ->> Initialize Physics Vectors <<-
mass = [m1,m2]
Pos = [x1s,y1s,x2s,y2s]
xPos = [x1s,x2s]
yPos = [y1s,y2s]
Force = [fx1s,fy1s,fx2s,fy2s]
xForce = [fx1s,fx2s]
yForce = [fy1s,fy2s]
Acc = [ax1s,ay1s,ax2s,ay2s]
xAcc = [ax1s,ax2s]
yAcc = [ay1s,ay2s]
Vel = [vx1s,vy1s,vx2s,vy2s]
xVel = [vx1s,vx2s]
yVel = [vy1s,vy2s]

simulate(Pos,Vel,Acc)

print(type(line))
print("-- Five --")

# ->> ANIMATE SIMULATION <<-
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=200, interval=20, blit=True)
#anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()

这让我很困惑:我知道这个错误通常是在你“未能解压对象列表”时给出的,正如这个问题Line2D的答案中提到的那样。为了解决这个问题,您应该在您尝试“解包”的变量旁边添加一个逗号。在这种情况下,当我初始化代码片段的顶部时,我肯定包含了那个逗号。所以我很困惑为什么我会收到这个错误信息?作为参考,我一直在遵循这个示例来创建动画情节,并且我相信我在很大程度上与他们的代码保持一致。line

此外,我创建了一些print()语句来帮助我查看代码执行的各个阶段。这是错误消息之前的输出:

-- One --
-- Two --
-- Three --
-- Four --
<class 'matplotlib.lines.Line2D'>
-- Five --

如您所见,line变量的类型lines.Line2D正好在模拟开始之前,这应该正是我们想要的(对吧?)。我怀疑一旦simulation()被调用,引擎盖下就会发生一些奇怪的事情,但我没有足够的能力来导航这个过程。

谁能帮我弄清楚我的代码出了什么问题?谢谢。

标签: pythonmatplotlibanimation

解决方案


推荐阅读