Matplotlib绘制动图
Matplotlib如何绘制动图
Matplotlib是非常著名的Python绘图库,支持非常复杂的底层定制化操作。本文通过Matplotlib中的动画绘制工具来讲解如何绘制动态图,首先讲解通过交互模式如何显示动态图,继而讲解通过两个动画类来实现动图地保存(GIF格式)。首先,需要明确,Matplotlib绘图有两种显示模式,分别为阻塞模式和交互模式,他们具体的说明如下。默认情况下,Matplotlib使用阻塞模式,要想打开交互模式需要通过下面的几个函数来做操作,下面直接列出要用的核心函数。plt.ion() # 打开交互模式 plt.ioff() # 关闭交互模式 plt.clf() # 清除当前的Figure对象 plt.pause() # 暂停GUI功能多少秒 1 2 3 4 然后就是要清楚,所谓的动图或者视频是怎么做到的,其实它们本质上就是很多静态图以较快的速度连续播放从而给人一种动感,利用Matplotlib绘制动图的原理也是一样的,遵循画布绘图->清理画布->画布绘图的循环就行了,不过这里注意,由于交互模式下绘图都是一闪而过,因此通过plt.pause(n)暂停GUI显示n秒才能得到连续有显示的图像。import matplotlib.pyplot as plt import numpy as np def io_test(): fig = plt.figure() # 生成画布 plt.ion() # 打开交互模式 for index in range(50): fig.clf() # 清空当前Figure对象 fig.suptitle("3d io pic") # 生成数据 point_count = 100 # 随机生成100个点 x = np.random.random(point_count) y = np.random.random(point_count) z = np.random.random(point_count) color = np.random.random(point_count) scale = np.random.random(point_count) * 100 ax = fig.add_subplot(111, projection="3d") # 绘图 ax.scatter3D(x, y, z, s=scale, c=color, marker="o") ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") # 暂停 plt.pause(0.2) # 关闭交互模式 plt.ioff() plt.show() if __name__ == '__main__': io_test() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 上述代码演示了三维空间如何动态显示100个随机点的变化,使用录制软件得到的动图如下,其本质就是不停显示不同的图像而已。很多时候我们的需求并不是在窗口中动态显示图像,还需要保存到本地GIF图像,显然使用录制工具是一个比较低效的用法,Matplotlib的animation模块提供了两个动画绘制接口,分别是FuncAnimation和ArtistAnimation,它们都是继承自TimedAnimation的类,因而也具有Animation对象的通用方法,如Animation.save()和Animation.to_html5_video()两个方法实例化一个Animation对象后均可调用,前者表示将动画保存为一个图像,后者表示将动画表示为一个HTML视频。下面给出上述两个类的构造函数所需参数,它们的主要参数也是类似的,都是一个Figure对象作为画布,然后一个对象作为更新的实现方式(前者需要一个反复绘图的更新函数,后者则为一个图像列表或者绘图对象列表)。ani = animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs) ani = animation.ArtistAnimation(fig, artists, *args, **kwargs) 1 2 相比较而言,我更喜欢使用FuncAnimation,它的使用要求简洁且定制化程度较高。但是如果想将很多图片合并为一个动图,那么ArtistAnimation是最合适的选择。下面的代码演示了如何保存一个动态变化渲染的柱状图,ArtistAnimation传入了一个图像序列,序列中每个元素为绘制的柱状图。然后通过使用Animation的save方法保存了动态图,**需要注意的是,这里有个动画写入器(writer)可以选择,默认不是pillow,我个人觉得pillow安装简单一些。