当用户确定打印数量时,使用Matplotlib打印动画

2024-10-01 16:32:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我将简单地解包这个问题:我正在用GUI创建一个n体模拟,用户可以在其中决定要模拟哪些行星并据此绘制。因此,在运行脚本之前,我不知道必须绘制什么。我发现绘制它很有挑战性,我想知道是否有任何见解可以给出如何做到这一点。对于3个机构,代码:

# #Animate
#Make the figure
fig=plt.figure(7, figsize=(11,8))
ax=fig.add_subplot(111,projection="3d")

#Create new arrays for animation, this gives you the flexibility
#to reduce the number of points in the animation if it becomes slow
r1_sol_anim=r1_sol[::1,:].copy()
r2_sol_anim=r2_sol[::1,:].copy()
r3_sol_anim=r3_sol[::1,:].copy()

#Set initial marker for planets, that is, blue,red and green circles at the initial positions
head1=[ax.scatter(r1_sol_anim[0,0],r1_sol_anim[0,1],r1_sol_anim[0,2],color="darkblue",marker="o",s=100,label="Sun")]
head2=[ax.scatter(r2_sol_anim[0,0],r2_sol_anim[0,1],r2_sol_anim[0,2],color="tab:red",marker="o",s=100,label="Earth")]
head3=[ax.scatter(r3_sol_anim[0,0],r3_sol_anim[0,1],r3_sol_anim[0,2],color="tab:green",marker="o",s=100,label="Mars")]

#Create a function Animate that changes plots every frame (here "i" is the frame number)
def Animate(i,head1,head2,head3,head4,head5):
    #Remove old markers
    head1[0].remove()
    head2[0].remove()
    head3[0].remove()


    #Plot the orbits (every iteration we plot from initial position to the current position)
    trace1=ax.plot(r1_sol_anim[:i,0],r1_sol_anim[:i,1],r1_sol_anim[:i,2],color="darkblue",label="Sun")
    trace2=ax.plot(r2_sol_anim[:i,0],r2_sol_anim[:i,1],r2_sol_anim[:i,2],color="tab:red",label="Earth")
    trace3=ax.plot(r3_sol_anim[:i,0],r3_sol_anim[:i,1],r3_sol_anim[:i,2],color="tab:green",label="Mars")

    #Plot the current markers
    head1[0]=ax.scatter(r1_sol_anim[i-1,0],r1_sol_anim[i-1,1],r1_sol_anim[i-1,2],color="darkblue",marker="o",s=100,label="Sun")
    head2[0]=ax.scatter(r2_sol_anim[i-1,0],r2_sol_anim[i-1,1],r2_sol_anim[i-1,2],color="tab:red",marker="o",s=100,label="Earth")
    head3[0]=ax.scatter(r3_sol_anim[i-1,0],r3_sol_anim[i-1,1],r3_sol_anim[i-1,2],color="tab:green",marker="o",s=100,label="Mars")

    return trace1,trace2,trace3,head1,head2,head3

#Add a few bells and whistles
ax.set_xlabel("x-coordinate",fontsize=14)
ax.set_ylabel("y-coordinate",fontsize=14)
ax.set_zlabel("z-coordinate",fontsize=14)
ax.set_xlim(-2.5e11, 2.5e11)
ax.set_ylim(-2.5e11, 2.5e11)
ax.set_zlim(-2.5e11, 2.5e11)
ax.set_box_aspect([1,1,1])
ax.set_title("Visualization of orbits of stars in a N-body system",fontsize=14)

anim=animation.FuncAnimation(fig,Animate, save_count=200, repeat=False,blit=False,fargs=(head1,head2,head3))

但是这需要知道有多少轨道或线需要被动画化,并且想知道是否有一种方法可以使它更普遍化。我目前正在修补的代码如下所示:

r_sol_anim=r_sol[::1,:].copy()

head = np.full((iterations,N*3),0)


#Set initial marker for planets, that is, blue,red and green circles at the initial positions
for i in range(N):
    head[:,i*3]=[ax.scatter(r_sol_anim[0,i*3],r_sol_anim[0,1+i*3],r_sol_anim[0,2+i*3],color=colours[i],marker="o",s=100,label=solarsystem.planets[i].name)]

#Create a function Animate that changes plots every frame (here "i" is the frame number)
def Animate(i,head):
    #Remove old markers
    head[0].remove()

    #Plot the orbits (every iteration we plot from initial position to the current position)
    for i in range(N):
        trace=ax.plot(r_sol_anim[:i,0+i*3],r_sol_anim[:i,1+i*3],r_sol_anim[:i,2+i*3],color=colours[i],label=solarsystem.planets[i].name)


    #Plot the current markers
    for i in range(N):
        head[0]=ax.scatter(r_sol_anim[i-1,0],r_sol_anim[i-1,1],r_sol_anim[i-1,2],color=colours[i],marker="o",s=100,label=solarsystem.planets[i].name)
    

    return trace,head

#Add a few bells and whistles
ax.set_xlabel("x-coordinate",fontsize=14)
ax.set_ylabel("y-coordinate",fontsize=14)
ax.set_zlabel("z-coordinate",fontsize=14)
# ax.set_xlim(-2.5e11, 2.5e11)
# ax.set_ylim(-2.5e11, 2.5e11)
# ax.set_zlim(-2.5e11, 2.5e11)
ax.set_box_aspect([1,1,1])
ax.set_title("Visualization of orbits of stars in a N-body system",fontsize=14)

for i in range(N):
    anim=animation.FuncAnimation(fig,Animate, save_count=200, repeat=False,blit=False,fargs=(head))

但我不确定我尝试的方式是否可能。有什么想法吗

在我的代码中,p.S r_sol_anim是一个(t,3N)数组,t是时间,N是行星。3N因为它是三维的,所以每个行星都有3个坐标来定位它


热门问题