让我先让大家知道,我对编程还是有点陌生,所以我确信我的代码在某些部分可能相当低效,有一些潜在的令人生厌的行。我事先道歉
不管怎么说,我正试图编写一个2D物理模拟器,模拟给定一组初始条件的两个天体之间的相互作用,然后为它们的轨迹设置动画。问题是,当我运行代码时,会出现以下错误:AttributeError: 'list' object has no attribute 'set_data'
,特别是引用了init()
中的line.set_data([],[])
命令。这个错误指向我在下面标记的第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
对象的列表”时出现的,如this question的答案中所述。要解决这个问题,您应该在试图“解包”的变量旁边加一个逗号。在本例中,当我朝代码段顶部初始化line
时,我肯定包含了那个逗号。所以我很困惑为什么我会收到这个错误信息?作为参考,我一直遵循this example来创建动画情节,我相信我在很大程度上与他们的代码是一致的
此外,我创建了一些print()
语句来帮助我查看代码执行的各个阶段。这是错误消息之前的输出外观:
-- One --
-- Two --
-- Three --
-- Four --
<class 'matplotlib.lines.Line2D'>
-- Five --
正如您所看到的,line
变量在模拟开始之前是lines.Line2D
类型的,这正是我们想要的(对吧?)。我怀疑一旦simulation()
被调用,引擎盖下会发生一些奇怪的事情,但我没有足够的能力来引导这个过程
有人能帮我找出代码中的错误吗?谢谢
目前没有回答
相关问题 更多 >
编程相关推荐