python - 动画情节“列表”对象没有属性“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()
被调用,引擎盖下就会发生一些奇怪的事情,但我没有足够的能力来导航这个过程。
谁能帮我弄清楚我的代码出了什么问题?谢谢。
解决方案
推荐阅读
- javascript - 图片无法获取父属性
- javascript - Python 漂亮的网页抓取模拟点击抓取所有页面
- python - 如何修复错误“ValueError:压缩距离矩阵必须仅包含有限值。” 在 seaborn 中使用 Yule 度量进行层次聚类
- html - URI Fragment 的落地位置是变量吗?或者它总是顶部?
- amazon-web-services - 直接从 URL 下载 zip 文件需要哪些存储桶权限?
- php - PHPUnit:使用返回 Iterator 对象的数据提供程序
- ios - SwiftUI,将文本呈现在 HStack 内的屏幕外
- python - 什么是在labview和python之间交换集群数据数组的简单方法
- angular - 在 Angular Autocomplete 中,我在建议中获取先前输入的值,而不是从数组中获取值
- django - 使用 django 文件系统从请求中保存文件