python 如何创建随时间变化的MatPlotLib或类似图形?

myzjeezk  于 2024-01-05  发布在  Python
关注(0)|答案(1)|浏览(205)

我试图做的是使用Matplotlib绘制轨道模拟的数据;下面是我试图实现的一个例子。x1c 0d1x
我有行星的数据,以及航天器在X,Y,Z,时间坐标(或者如果必要的话,我可以在其他坐标系中获得它)相对于太阳。
我怎么能做一个这样的GIF?
我试着只使用x,y的pyplot,但不是移动GIF,我只得到一个平面图像。(正如预期的那样,因为PyPlot只能制作静态图)。任何帮助/指针,我可以看非常感谢。

efzxgjgh

efzxgjgh1#

可以使用matplotlib FuncAnimation工具根据matplotlib中的数据创建动画。其思想是将动画视为帧的集合,并根据帧号定义每帧的图形/内容(假设这些帧是按升序排列的)。更多关于matplotlib动画的详细信息可以在官方网站的这个页面上找到:Matplotlib Animations。答案的其余部分专门针对该问题提供了一些指导。

最终结果

下面是我用matplotlib FuncAnimation创建的一个虚拟动画,它是基于问题的思想(虽然有虚拟数据)。
x1c 0d1x的数据

代码

下面是生成上述动画的代码-

  1. from matplotlib.animation import FuncAnimation
  2. import matplotlib.pyplot as plt
  3. import math
  4. # dummy parameters, replace them with your own
  5. sun_x, sun_y = 0, 0
  6. voyager1_theta, voyager1_speed, voyager1_radius = 0, 0.003*math.pi, 40
  7. planet1_theta, planet1_speed, planet1_radius = 0, 0.002*math.pi, 40
  8. planet2_theta, planet2_speed, planet2_radius = 0, 0.001*math.pi, 90
  9. fps = 10 # frames per second in animation
  10. total_time = 5 # in seconds, total time of animation
  11. time_ratio = 100 # in seconds, how many seconds in reality for every second on animation
  12. # extra calculations
  13. interval = 1/fps # in seconds
  14. total_frames = total_time * fps
  15. voyager_x_data = []
  16. voyager_y_data = []
  17. fig, ax = plt.subplots()
  18. def update(frame):
  19. # this function accepts the frame-number as frame and creates the figure for it
  20. global ax
  21. # dummy calculations, replace them with your own calculations
  22. time = frame*interval*time_ratio # in seconds
  23. voyager_x = (voyager1_radius+time/20) * math.cos(voyager1_speed*time + voyager1_theta)
  24. voyager_y = (voyager1_radius+time/20) * math.sin(voyager1_speed*time + voyager1_theta)
  25. voyager_x_data.append(voyager_x)
  26. voyager_y_data.append(voyager_y)
  27. planet1_x = planet1_radius * math.cos(planet1_speed*time + planet1_theta)
  28. planet1_y = planet1_radius * math.sin(planet1_speed*time + planet1_theta)
  29. planet2_x = planet2_radius * math.cos(planet2_speed*time + planet2_theta)
  30. planet2_y = planet2_radius * math.sin(planet2_speed*time + planet2_theta)
  31. # plotting
  32. ax.clear() # clear the figure (to remove the contents of last frame)
  33. ax.set_ylim(-100,100)
  34. ax.set_xlim(-100,100)
  35. ax.set_aspect('equal')
  36. ax.set_title('Time = {:.3f} sec'.format(time))
  37. ax.scatter(sun_x, sun_y, color = 'yellow', marker = 'o') #, label='Sun')
  38. ax.scatter(planet1_x, planet1_y, color = 'blue', marker = 'o') #, label = 'Planet1')
  39. ax.scatter(planet2_x, planet2_y, color = 'green', marker = 'o') #, label = 'Planet2')
  40. ax.plot(voyager_x_data, voyager_y_data, color = 'red')
  41. ax.scatter(voyager_x, voyager_y, color = 'red', label = 'Voyager')
  42. ax.legend()
  43. anim = FuncAnimation(fig, update, frames = range(total_frames), interval = interval*1000) # multiplying by 1000 to convert sec into milli-sec
  44. anim.save('result.gif', fps = fps) # replace the name of file with your own path and name
  45. #plt.show() # uncomment this line and comment out the second-last line to see in realtime instead of saving

字符串
解释说明
代码中的注解包含了阅读和使用代码时所需的所有辅助信息。本节包含了整体说明。
1.创建数据。您可以从任何数据库中计算或加载数据。在上面的代码中,我们正在计算数据。在创建帧时,更新函数中也会计算一些数据。此外,代码中还有一些额外的方便参数,如fpstotal_timetime_ratio
1.初始化matplotlib图形和轴(fig, ax = plt.subplots()),然后定义update函数,该函数将帧编号作为输入并创建该帧编号的图形。
1.使用FuncAnimation创建动画。在代码中,我们使用FuncAnimation(fig, update, frames = range(total_frames), interval = interval*1000)创建动画。我们指定帧以匹配我们想要的时间,并指定间隔以匹配我们想要的动画中的FPS。
1.最后,查看/保存动画。要查看,请调用plt.show()。要保存,请调用anim.save(),其中指定输出文件的路径沿着文件名和fps,以匹配我们想要的FPS。

备注

1.指定给anim.save()的文件名扩展名用于确定导出格式。在ffmpeg的帮助下,还支持其他格式。要获得对其他格式的支持,请安装ffmpeg并在anim.save()中指定writer='ffmpeg'
1.在实时查看动画时,例如使用plt.show(),将frames=None设置为FuncAnimation(),因为我们不想指定动画运行的时间。我们希望它在我们查看时就运行。

展开查看全部

相关问题