python - Python:使用 matplotlib.animation 为两个线条列表设置动画,但一次只显示一组线条
问题描述
试图绘制具有螺旋线和收缩、旋转多边形的追踪曲线,在每个当前点问题=无法同时绘制视线和主线图形在收缩的多边形之间来回滑动(由 SightLine 描述)和主要追踪曲线(MainLines)
当一次单独制作一个动画时,多边形和追踪曲线绘制得很好,但我无法让它们在同一个图形上一起工作。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
%matplotlib notebook
plt.style.use('dark_background')
NumOfPoints = 6
deltaT = 0.005
duration = 50
steps = int(duration / deltaT)
speed = 0.2
num = 0
CurrentXPoints = []
CurrentYPoints = []
DeltaX = np.zeros(NumOfPoints)
DeltaY = np.zeros(NumOfPoints)
MagnitudeDelta = np.zeros(NumOfPoints)
VelocityX = np.zeros(NumOfPoints)
VelocityY = np.zeros(NumOfPoints)
#Creates Initial Points by equally spacing the points around a polygon inscribed around circle
for i in range(0,NumOfPoints):
x = np.cos(((i/NumOfPoints)*2)*np.pi)
y = np.sin(((i/NumOfPoints)*2)*np.pi)
CurrentXPoints.append(x)
CurrentYPoints.append(y)
AllXPoints = np.array([CurrentXPoints])
AllYPoints = np.array([CurrentYPoints])
#Fills out both AllXPoints and AllYPoints with all points in duration
for i in range(int(steps)):
for j in range(0,NumOfPoints-1): #Calculates deltaX and deltaY at this timestep
DeltaX[j] = CurrentXPoints[j+1] - CurrentXPoints[j]
DeltaY[j] = CurrentYPoints[j+1] - CurrentYPoints[j]
DeltaX[NumOfPoints-1] = CurrentXPoints[0] - CurrentXPoints[NumOfPoints-1]
DeltaY[NumOfPoints-1] = CurrentYPoints[0] - CurrentYPoints[NumOfPoints-1]
for j in range(0,NumOfPoints): # calculats new X and Y Points
MagnitudeDelta[j] = ((DeltaX[j])**2 + (DeltaY[j])**2)**(1/2)
VelocityX[j] = speed * (DeltaX[j]/MagnitudeDelta[j])
VelocityY[j] = speed * (DeltaY[j]/MagnitudeDelta[j])
CurrentXPoints[j] += deltaT * VelocityX[j]
CurrentYPoints[j] += deltaT * VelocityY[j]
CurrentXPointsArr = np.array(CurrentXPoints)
CurrentYPointsArr = np.array(CurrentYPoints)
AllXPoints = np.vstack((AllXPoints,CurrentXPointsArr))
AllYPoints = np.vstack((AllYPoints,CurrentYPointsArr))
fig = plt.figure(figsize=(5,5))
ax = plt.axes()
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
MainLines = []
SightLines= []
AllLines = MainLines + SightLines
for i in range(NumOfPoints):
line, = ax.plot([AllXPoints[j][i] for j in range(steps)], [AllYPoints[j][i] for j in range(steps)])
MainLines.append(line)
SightLines.append(line)
def UpdateMain(num, AllXPoints, AllYPoints, MainLines):
for line in MainLines:
position = MainLines.index(line)
line.set_data([AllXPoints[i][position] for i in range(num)], [AllYPoints[i][position] for i in range(num)])
def UpdateSight(num, AllXPoints, AllYPoints, SightLines):
for line in SightLines:
position = SightLines.index(line)
if position < (NumOfPoints-1):
line.set_data([AllXPoints[num][position],AllXPoints[num][position+1]],
[AllYPoints[num][position],AllYPoints[num][position+1]])
else:
line.set_data([AllXPoints[num][position],AllXPoints[num][0]],
[AllYPoints[num][position],AllYPoints[num][0]])
ani1 = animation.FuncAnimation(fig, UpdateMain,steps, fargs=[AllXPoints, AllYPoints, MainLines],
interval=1, blit=True)
ani2 = animation.FuncAnimation(fig, UpdateSight,steps, fargs=[AllXPoints, AllYPoints, SightLines],
interval=1, blit=True)
plt.show()
解决方案
首先,您应该只使用一个FuncAnimation
更新所有艺术家的。您的代码的主要问题是行
for i in range(NumOfPoints):
line, = ax.plot([AllXPoints[j][i] for j in range(steps)], [AllYPoints[j][i] for j in range(steps)])
MainLines.append(line)
SightLines.append(line)
您正在创建一位艺术家 ( line
) 并将其分配给两个不同的列表。如果您为每个列表创建 2 行不同的行,则输出符合预期。
完整的工作代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
%matplotlib notebook
plt.style.use('dark_background')
NumOfPoints = 6
deltaT = 0.005
duration = 50
steps = int(duration / deltaT)
speed = 0.2
num = 0
CurrentXPoints = []
CurrentYPoints = []
DeltaX = np.zeros(NumOfPoints)
DeltaY = np.zeros(NumOfPoints)
MagnitudeDelta = np.zeros(NumOfPoints)
VelocityX = np.zeros(NumOfPoints)
VelocityY = np.zeros(NumOfPoints)
def update(num, AllXPoints, AllYPoints, MainLines, SightLines):
out = []
out.append(UpdateMain(num, AllXPoints, AllYPoints, MainLines))
out.append(UpdateSight(num, AllXPoints, AllYPoints, SightLines))
return out
def UpdateMain(num, AllXPoints, AllYPoints, MainLines):
for line in MainLines:
position = MainLines.index(line)
line.set_data([AllXPoints[i][position] for i in range(num)], [AllYPoints[i][position] for i in range(num)])
return MainLines
def UpdateSight(num, AllXPoints, AllYPoints, SightLines):
for line in SightLines:
position = SightLines.index(line)
if position < (NumOfPoints-1):
line.set_data([AllXPoints[num][position],AllXPoints[num][position+1]],
[AllYPoints[num][position],AllYPoints[num][position+1]])
else:
line.set_data([AllXPoints[num][position],AllXPoints[num][0]],
[AllYPoints[num][position],AllYPoints[num][0]])
return SightLines
#Creates Initial Points by equally spacing the points around a polygon inscribed around circle
for i in range(0,NumOfPoints):
x = np.cos(((i/NumOfPoints)*2)*np.pi)
y = np.sin(((i/NumOfPoints)*2)*np.pi)
CurrentXPoints.append(x)
CurrentYPoints.append(y)
AllXPoints = np.array([CurrentXPoints])
AllYPoints = np.array([CurrentYPoints])
#Fills out both AllXPoints and AllYPoints with all points in duration
for i in range(int(steps)):
for j in range(0,NumOfPoints-1): #Calculates deltaX and deltaY at this timestep
DeltaX[j] = CurrentXPoints[j+1] - CurrentXPoints[j]
DeltaY[j] = CurrentYPoints[j+1] - CurrentYPoints[j]
DeltaX[NumOfPoints-1] = CurrentXPoints[0] - CurrentXPoints[NumOfPoints-1]
DeltaY[NumOfPoints-1] = CurrentYPoints[0] - CurrentYPoints[NumOfPoints-1]
for j in range(0,NumOfPoints): # calculats new X and Y Points
MagnitudeDelta[j] = ((DeltaX[j])**2 + (DeltaY[j])**2)**(1/2)
VelocityX[j] = speed * (DeltaX[j]/MagnitudeDelta[j])
VelocityY[j] = speed * (DeltaY[j]/MagnitudeDelta[j])
CurrentXPoints[j] += deltaT * VelocityX[j]
CurrentYPoints[j] += deltaT * VelocityY[j]
CurrentXPointsArr = np.array(CurrentXPoints)
CurrentYPointsArr = np.array(CurrentYPoints)
AllXPoints = np.vstack((AllXPoints,CurrentXPointsArr))
AllYPoints = np.vstack((AllYPoints,CurrentYPointsArr))
fig = plt.figure(figsize=(5,5))
ax = plt.axes()
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
MainLines = []
SightLines= []
AllLines = MainLines + SightLines
for i in range(NumOfPoints):
line1, = ax.plot([AllXPoints[j][i] for j in range(steps)], [AllYPoints[j][i] for j in range(steps)])
line2, = ax.plot([AllXPoints[j][i] for j in range(steps)], [AllYPoints[j][i] for j in range(steps)])
MainLines.append(line1)
SightLines.append(line2)
ani = animation.FuncAnimation(fig, update, steps, fargs=[AllXPoints, AllYPoints, MainLines, SightLines], interval=1, blit=True)
plt.show()
推荐阅读
- excel - 这个 $ExternalData_1 在 Excel PowerPivot 和 PowerQuery 中应该是什么意思?
- swift - Firestore 批处理集仅插入最后一项
- ios - Swift 如何根据单击的工具栏按钮将用户引导到不同的视图控制器
- mysql - 以写列的顺序排序
- opendj - 无法将属性添加到 OpenDJ LDAP 中的条目
- itext - PDFA 文档缺少注释和标记
- amazon-web-services - 如何限制用户使用 IAM 从亚马逊 S3 下载数据?
- sql - 需要 sql 查询来匹配三个值
- javascript - Photoshop 脚本数组到 json
- angular - Angular中伊斯坦布尔覆盖报告中的标记异常