matplotlib中的几何图形视频

c9x0cxw0  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(169)

我有三个圆的位置数据,我想制作这些移动圆的动画。我看过很多函数的动画,但我无法制作几何形状的动画。下面是我写的一些代码,用来创建三个圆在时间变化位置的图。

import matplotlib.pyplot as plt
import numpy as np

# Just a minimal example mock data
positions=np.zeros((3,2,100))
positions[0,0,:]=np.linspace(-10,10,100)
positions[0,1,:]=np.linspace(-10,10,100)
positions[1,0,:]=7*np.cos(np.linspace(0,30,100))
positions[1,1,:]=7*np.sin(np.linspace(0,30,100))
positions[2,0,:]=5*np.sin(np.linspace(0,30,100))
positions[2,1,:]=np.linspace(-10,10,100)

# My code
for i in range(100):
    fig, ax = plt.subplots()
    ax.set_xlim(-10, 10)
    ax.set_ylim(-10, 10)
    circle1=plt.Circle((positions[0,0,i], positions[0,1,i]),1)
    circle2=plt.Circle((positions[1,0,i], positions[1,1,i]),1)
    circle3=plt.Circle((positions[2,0,i], positions[2,1,i]),1)
    ax.add_patch(circle1)
    ax.add_patch(circle2)
    ax.add_patch(circle3)
    ax.axis("equal")

positions是一个数组:第一个索引标记不同的圆,第二个索引标记x和y坐标,第三个索引标记第i个时间步长。我能够随着这些形状的位置变化来创建它们的绘图。但是现在我想把这些图像放在一起来制作一个动画。

3bygqnnd

3bygqnnd1#

需要调用animate函数。
(还有其他方法。根据绘制绘图的方式,您可以自己循环,并更新数据。但对于这种动画,animate更好)。

# Let start with import. Btw, you should include those in your question.
# The "minimal reproducible example" is an example that is minimal, in the sense
# that it contains only what is strictly needed for your question, 
# with nothing from your app that is not needed.
# But it contains also ALL that is needed to reproduce problem.
# You wouldn't want someone to reply to you "if your code doesn't work
# it is because you did not import matplotlib". But if you don't include
# it...
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as anim

# Likewise, a minimal reproducible example should include mock data
# Again, no need for the real one. I am sure they are complicated to
# create, and this complication if off topic to your question
# But anything, just to illustrate the question.
positions=np.zeros((3,2,100))
positions[0,0,:]=np.linspace(-10,10,100)
positions[0,1,:]=np.linspace(-10,10,100)
positions[1,0,:]=7*np.cos(np.linspace(0,30,100))
positions[1,1,:]=7*np.sin(np.linspace(0,30,100))
positions[2,0,:]=5*np.sin(np.linspace(0,30,100))
positions[2,1,:]=np.linspace(-10,10,100)

# That preamble done, we start with  something very similar to one loop
# of your code, just to create the plot
i=0 # That is because I am lazy, and it's easier than replacing i by 0 in the following lines
fig, ax = plt.subplots()
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
circle1=plt.Circle((positions[0,0,i], positions[0,1,i]),1)
circle2=plt.Circle((positions[1,0,i], positions[1,1,i]),1)
circle3=plt.Circle((positions[2,0,i], positions[2,1,i]),1)
ax.add_patch(circle1)
ax.add_patch(circle2)
ax.add_patch(circle3)
#ax.axis("equal") # I comment this one because it breaks xlim/ylim

# So now, we have 1 plot, with the circles
# We DONT just redo it to with other animations. That wouldn't work (it creates
# a new figure) But even if it were working, that would be hugely slow
# Creating a figure is way more expansive than just updating some 
# parameters of it

# What we do, is to regularly update the plot data, here, the centers
# of the 3 circles
# In this case (again, it could be done other way), I do so using a
# animation function that will be called back iteratively by the
# rendering loop

# animate has 1 arg. That is `i`, the frame number (the exact same i of your code)
# And returns a list of `artist` that is of "things" whose you want to
# update the data.
# and before returning it does the job of updating the data
def animate(i):
   # We update the center of each of the 3 circles
   circle1.set_center(positions[0,:,i])
   circle2.set_center(positions[1,:,i])
   circle3.set_center(positions[2,:,i])
   # And return a list of those 3 circles so that the main loop knows
   # that they were changed
   return [circle1, circle2, circle3]

# This is how we ensure `animate` is called 100 times. With 20ms between each call. 
# In fact, because of the last parameter, it is called infinitely, because
# we loop back to the beginning 
theAnimation = anim.FuncAnimation(fig, animate, frames=100, interval=20, blit=True )
#theAnimation.save("result.gif")
plt.show()

所以,粗略地说,除了大量的注解,这是你的代码+ 3行代码,set_center在每个循环中要做的,你自己的循环只做一次。这里的循环是由FuncAnimation迭代地调用animate回调完成的。
而且,我会编辑你的问题,包括“最小可重复的例子”(但如果你认为这与你的意图相矛盾,你可以自由地编辑回来)。我鼓励你在未来的问题中尝试使用同样的例子。

相关问题