简介

Matplotlib是非常著名的Python绘图库,支持非常复杂的底层定制化操作。本文通过Matplotlib中的动画绘制工具来讲解如何绘制动态图,首先讲解通过交互模式如何显示动态图,继而讲解通过两个动画类来实现动图地保存(GIF格式)。

显示动态图

首先,需要明确,Matplotlib绘图有两种显示模式,分别为阻塞模式交互模式,他们具体的说明如下。

  1. 阻塞模式,该模式下绘制地图地显示必须使用plt.show()进行展示(默认会弹出一个窗口),代码会运行到该行阻塞不继续执行,直到关闭这个展示(默认是关闭弹出的显示窗口,Pycharm等集成开发环境会自动捕获图片然后跳过阻塞)。
  2. 交互模式,该模式下任何绘图相关的操作如plt.plot()会立即显示绘制的图形然后迅速关闭,继续代码的运行,不发生阻塞。

默认情况下,Matplotlib使用阻塞模式,要想打开交互模式需要通过下面的几个函数来做操作,下面直接列出要用的核心函数。

plt.ion()  # 打开交互模式
plt.ioff()  # 关闭交互模式
plt.clf()  # 清除当前的Figure对象
plt.pause()  # 暂停GUI功能多少秒

然后就是要清楚,所谓的动图或者视频是怎么做到的,其实它们本质上就是很多静态图以较快的速度连续播放从而给人一种动感,利用Matplotlib绘制动图的原理也是一样的,遵循画布绘图->清理画布->画布绘图的循环就行了,不过这里注意,由于交互模式下绘图都是一闪而过,因此通过plt.pause(n)暂停GUI显示n秒才能得到连续有显示的图像

import matplotlib.pyplot as plt
import numpy as npdef 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) * 100ax = 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()

上述代码演示了三维空间如何动态显示100个随机点的变化,使用录制软件得到的动图如下,其本质就是不停显示不同的图像而已。

动图保存

很多时候我们的需求并不是在窗口中动态显示图像,还需要保存到本地GIF图像,显然使用录制工具是一个比较低效的用法,Matplotlib的animation模块提供了两个动画绘制接口,分别是FuncAnimationArtistAnimation,它们都是继承自TimedAnimation的类,因而也具有Animation对象的通用方法,如Animation.save()Animation.to_html5_video()两个方法实例化一个Animation对象后均可调用,前者表示将动画保存为一个图像,后者表示将动画表示为一个HTML视频。

  • FuncAnimation: 通过反复调用同一更新函数来制作动画。
  • ArtistAnimation: 通过调用一个固定的Artist对象来制作动画,例如给定的图片序列或者Matplotlib的绘图对象。

下面给出上述两个类的构造函数所需参数,它们的主要参数也是类似的,都是一个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)

相比较而言,我更喜欢使用FuncAnimation,它的使用要求简洁且定制化程度较高。但是如果想将很多图片合并为一个动图,那么ArtistAnimation是最合适的选择。

下面的代码演示了如何保存一个动态变化渲染的柱状图,ArtistAnimation传入了一个图像序列,序列中每个元素为绘制的柱状图。然后通过使用Animationsave方法保存了动态图,**需要注意的是,这里有个动画写入器(writer)可以选择,默认不是pillow,我个人觉得pillow安装简单一些。

import matplotlib.pyplot as plt
import matplotlib.animation as animationfig, ax = plt.subplots()
x, y, tmp = [], [], []for i in range(10):x.append(i)y.append(i+1)temp = ax.bar(x, height=y, width=0.3)tmp.append(temp)ani = animation.ArtistAnimation(fig, tmp, interval=200, repeat_delay=1000)
ani.save("bar.gif", writer='pillow')

上面代码的执行结果如下图。

接着,演示使用范围更广的FuncAnimation如何使用。下面的代码中,动态展示了梯度下降在三维图上的优化过程,其中最为核心的代码如下。用于构造Animation对象的除了画布就是一个更新函数,在这个更新函数内部多次绘制散点图从而形成动态效果, frames是帧数,如果设置了这个帧数,那么update函数第一个参数必须有一个num占位,这个numAnimation对象维护,每次内部执行update会自动递增,后面的参数列表fargs只需要传入除了num后面的参数即可。

def update(num, x, y, z, ax):x, y, z = x[:num], y[:num], z[:num]ax.scatter3D(x, y, z, color='black', s=100)return axani = animation.FuncAnimation(fig, update, frames=25, fargs=(x_list, y_list, z_list, ax3d), interval=50, blit=False)

上面的代码演示效果如下图,完整的代码附在文末补充说明中。

补充说明

本文介绍了如何使用Matplotlib绘制动态图,主要通过交互模式和animation模块进行,如果觉得有所帮助,欢迎点赞。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animationdef GD(x0, y0, lr, epoch):f = lambda x, y: x ** 2 - y ** 2g_x = lambda x: 2 * xx, y = x0, y0x_list, y_list, z_list = [], [], []for i in range(epoch):x_list.append(x)y_list.append(y)z_list.append(f(x, y) * 1.01)grad_x, grad_y = g_x(x), g_x(y)x -= lr * grad_xy -= lr * grad_yprint("Epoch{}: grad={} {}, x={}".format(i, grad_x, grad_y, x))if abs(grad_x) < 1e-6 and abs(grad_y) < 1e-6:breakreturn x_list, y_list, z_listdef update(num, x, y, z, ax):x, y, z = x[:num], y[:num], z[:num]ax.scatter3D(x, y, z, color='black', s=100)return axdef draw_gd():fig = plt.figure()x, y = np.meshgrid(np.linspace(-3, 3, 1000), np.linspace(-3, 3, 1000))z = x ** 2 - y ** 2ax3d = plt.gca(projection='3d')ax3d.set_xlabel("X")ax3d.set_ylabel("Y")ax3d.set_zlabel("Z")plt.tick_params(labelsize=10)ax3d.plot_surface(x, y, z, cstride=20, rstride=20, cmap="jet")x_list, y_list, z_list = GD(-3, 0, 0.01, 100)x_list, y_list, z_list = np.array(x_list), np.array(y_list), np.array(z_list)ani = animation.FuncAnimation(fig, update, frames=25, fargs=(x_list, y_list, z_list, ax3d), interval=50, blit=False)ani.save('test.gif')if __name__ == '__main__':draw_gd()

Matplotlib绘制动图相关推荐

  1. 在Python3里使用matplotlib绘折线图和散点图

    网上关于Python使用matplotlib包进行绘图的文章不少,自己写一遍掌握得才更好.matplotlib是用于创建二维图表和图形的库,它不在标准python库之中,需要单独安装. 安装 在win ...

  2. matplot绘制动图

    import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import numpy as np pl ...

  3. python使用matplotlib绘制饼状图

    python使用matplotlib绘制饼状图 Python绘图需要下载安装matplotlib模块,它是一个数学绘图库,我们将使用它来制作简单的图表. 绘制饼状图 代码一: import matpl ...

  4. python绘制饼状图图例_python matplotlib饼状图参数及用法解析

    这篇文章主要介绍了python matplotlib饼状图参数及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在python的matplo ...

  5. python matplotlib画折线图_python使用matplotlib绘制折线图教程

    matplotlib简介 matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序 ...

  6. python画曲线图例-python使用matplotlib绘制折线图教程

    matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中. 它的文档相当完备,并 ...

  7. 如何使用python画折线图-python使用matplotlib绘制折线图教程

    matplotlib简介 matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序 ...

  8. Python matplotlib绘制雷达图

    Python matplotlib绘制雷达图 本篇文章介绍使用matplotlib绘制雷达图. 雷达图也被称为网络图,蜘蛛图,星图,蜘蛛网图,是一个不规则的多边形.雷达图可以形象地展示相同事物的多维指 ...

  9. matplotlib绘制折线图的柱状图

    1. matplotlib绘制折线图 我们使用matplotlib绘图库绘制一个温度/湿度折线图 绘制折线图使用的是pylot库的plot函数,该函数参数如下 plot(x,y,color,marke ...

  10. matplotlib中箱线图、极线图、阶梯图的绘制

    本文介绍matplotlib中箱线图.极线图.阶梯图的绘制. 箱线图的绘制: 箱线图又称为盒须图.盒式图,是一种用作显示一组数据分散情况的统计图.主要用于反映原始数据分布的特征. 代码编写: impo ...

最新文章

  1. vue中子组件和子组件之间怎么通信_vue.js组件之间如何通信?
  2. 格式说明_法律文书:公司单位民事起诉状格式范本及说明,最高人民法院2016...
  3. 【NLP】从0梳理1场NLP赛事!
  4. 统计学习方法第八章作业:分类问题AdaBoost算法、回归问题提升树算法 代码实现
  5. 用python写linux中的ls,Python实现Linux环境下的ls命令
  6. win10怎么把c盘锁住_老司机教你win10下怎么清理c盘
  7. CPU高负载排查小技巧(2分钟速读版),细心的优化可能为公司节省一个亿!
  8. python django项目实例_最新Django项目实战-从零开发NB的任务平台python视频学习教程...
  9. 第一章节 ASP.NET Web应用程序基础(二)
  10. 高光谱图像处理和分析软件(包含雷尼绍Renishaw wdf 文件导入解析功能)
  11. ddk开发 c语言,ddk_helloWDM_原代码是网上高手的杰作
  12. 批处理注释bat注释一行_注释和注释处理器入门指南
  13. sr里简体中文的代码_各国语言代码大全Locale ID (LCID)表
  14. 防火墙单个ip映射多台服务器,使用防火墙构建器管理多个服务器的单个防火墙策略...
  15. twisted中的延迟(deferred)(一)
  16. raid卷构建实操(raid0、raid1、raid5、raid6以及raid10),可跟做
  17. 机器学习预测股票收益(一)之随机森林模型
  18. SAA 心理素质差差的
  19. 程序坞如何在主屏幕和副屏幕中自由切换【Mac分屏】
  20. 【学习进阶】提问的智慧【转载】

热门文章

  1. Learning Git Branching 题解(基础、高级、Git远程仓库)
  2. Amesim学习——弹球仿真
  3. Mac运行ftp报错Error: JAVA_HOME is not defined correctly.
  4. Android短信验证码控件,Android中实现短信验证码自动填入
  5. Diligent新聘全球合作伙伴关系高级副总裁
  6. PgRGGmiCst
  7. python 身份证实名认证
  8. 频域滤波—方波变换中的沃尔什变换与哈达玛变换
  9. VOT目标路径可视化
  10. LINUX HTB队列规定用户指南