使用matplotlib制作动态图

使用matplotlib制作动态图

    • 一、简介
    • 二、模块简介
      • 1. **FuncAnimation**类介绍
      • 2. 定义动画更新函数
    • 三、使用matplotlib制作动画
      • 1.一步法制作动态图片
      • 2. 两步法制作动态图片

一、简介

matplotlib(https://matplotlib.org/)是一个著名的python绘图库,由于其灵活强大的绘图功能使得在python中可视化变得非常容易,关于matplotlib的基础知识这里不再介绍,有疑问可以去官网翻Tutorials和example学习。由于我们实际使用时常常是绘制静态图,忽略了matplotlib的动态图生成功能,同时matplotlib生成动态图的功能不是非常友善,因此大部分人在真的需要制作动态图时都会选择先用matplotlib生成一系列静态图片,然后再用其它相对比较容易使用的第三方python库生成动态图,如imageio(https://imageio.readthedocs.io/en/stable/#), 或者使用其它工具,如Matlab。这里打算简单介绍一下在matplotlib库中制作动态图的方法。

二、模块简介

matplotlib的animation模块提供了动态图制作功能,animation类提供了两个方法来生成动态图,即FuncAnimationArtistAnimation,这里我们使用FuncAnimation方法重复调用函数来生成图片。

1. FuncAnimation类介绍

FuncAnimation类的主要参数包括:

  • fig: 每一帧画面绘制使得Figure对象
  • func: 定义动画每一帧的更新函数,通常这一函数需要包含额外参数,此时可以用functools.partial来生成。
  • frames:可以是可迭代对象,整数,或者生成函数或者缺省。
  • init_func:初始化函数
  • inteval:每一帧画面的停留时间
  • repeat:当动态图中所有帧都播放完了之后是否重复播放
  • bilt:是否使用blitting来优化绘图

2. 定义动画更新函数

FunAnimation类中,更新函数在每一帧中都会被重新调用,通过在更新函数中更改一些绘图函数的数据,在每一帧我们就能得到不同的图片,然后FunAnimation的Writer(后端)将这些图片组合就能得到动态图片。关于更新函数的一些需要注意的地方是:

  • 如果设置了bilt == True,更新函数的最后就需要返回所有被修改或创建的Artists的引用变量
  • 生成函数的第一个传入参数必须是当前的帧数,其具体值可以通过frames参数定义,可以是可迭代类型或整数

三、使用matplotlib制作动画

1.一步法制作动态图片

由于matplotlib本身自带强大的绘图功能,因此我们可以不用生成图片,直接在初始绘图的基础上通过更新函数来修改绘图数据,一步直接生成动态图片,方便快捷,以下是代码:

import numpy as np
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
from functools import partial### 绘制y=sin(2pi(x+t/t_0))*sin(2pi(t/t_0))
def getSinx_t(t=0, t_0=120, x_count=1e5):x = np.linspace(0.0, 1.0, int(x_count))y = np.sin(2.0*np.pi*(x + t/t_0))*np.sin(t/t_0*2.0*np.pi)return x, y### 图片初始化
fig, ax = plt.subplots(dpi=100)
ax.set_aspect('auto')
ax.set_xlim((0.0, 1.0))
ax.set_ylim((-1.0, 1.0))
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title(r'$y=sin[2\pi(x+t/t_0)]*sin(2\pi t/t_0)$')### 绘制初始曲线
x, y = getSinx_t()
y_up = y[np.where(y>0)]
x_up = x[np.where(y>0)]
x_dn = x[np.where(y<0)]
y_dn = y[np.where(y<0)]
plot_line = ax.plot(x, y)
plot_hline = ax.hlines(y=0.0, xmin=0.0, xmax=1.0, linestyles='dashed', colors='grey')
fill_xy_up = ax.fill_between(x=x_up, y1=y_up, y2=0, color='red', alpha=0.3)
fill_xy_dn = ax.fill_between(x=x_dn, y1=y_dn, y2=0, color='green', alpha=0.3)
plot_text = ax.text(x=0.8, y=0.75, s='t=0', fontsize=16, fontfamily='cursive')### 定义动画更新函数
def UpdateFigure(num, f_plot_line, f_fill_xy_up, f_fill_xy_dn, f_plot_text):x_update, y_update = getSinx_t(t=num)f_plot_line[0].set_data(x_update, y_update)f_plot_text.set_text('t={}'.format(num))x_up = x_update[np.where(y_update>0)]y_up = y_update[np.where(y_update>0)]xy_up1 = np.column_stack((x_up, y_up))xy_up2 = np.column_stack((x_up[::-1], np.zeros(x_up.shape)))x_dn = x_update[np.where(y_update<0)]y_dn = y_update[np.where(y_update<0)]xy_dn1 = np.column_stack((x_dn, y_dn))xy_dn2 = np.column_stack((x_dn[::-1], np.zeros(x_dn.shape)))f_fill_xy_up.set_verts([np.vstack((xy_up1, xy_up2))])f_fill_xy_dn.set_verts([np.vstack((xy_dn1, xy_dn2))])return [f_plot_line[0], f_fill_xy_up, f_fill_xy_dn, f_plot_text]### 创建FunAnimation对象
ani = FuncAnimation(fig, partial(UpdateFigure, f_plot_line=plot_line, f_fill_xy_up=fill_xy_up,f_fill_xy_dn=fill_xy_dn,f_plot_text=plot_text),np.arange(120),blit=True)### 保存动态图片
ani.save('sinxt.gif', fps=60)  

以下为得到的动态图片:
在这里插入图片描述

2. 两步法制作动态图片

所谓两步法是指,首先用matplotlib生成一系列静态图片,然后结合matplotlib.image.imread读取图片功能和matplotlib.axes.Axes.imshow展示图片功能,来动态地更新图片,这种方法相比于上一种方法稍微复杂,但是这种方法灵活性更高,同时也可以用来组合一些非matplotlib生成的图片。以下为代码:

import matplotlib.pyplot as plt
import matplotlib.image as mimg
from matplotlib.animation import FuncAnimation
import numpy as np
from functools import partial
import os### 绘制y=cos(2pi(x+t/t_0))*cos(2pi(t/t_0))
def getCosx_t(t=0, t_0=120, x_count=1e5):x = np.linspace(0.0, 1.0, int(x_count))y = np.cos(2.0*np.pi*(x + t/t_0))*np.cos(t/t_0*2.0*np.pi)return x, yfig_count = 120             # 图片总数### 定义生成所有图片的函数
def getFigrues(fig_count):try:os.mkdir('fig')except FileExistsError:print("Dir Exist!")for i in range(fig_count):fig, ax = plt.subplots(dpi=100)ax.set_aspect('auto')ax.set_xlim((0.0, 1.0))ax.set_ylim((-1.0, 1.0))ax.set_xlabel('x')ax.set_ylabel('y')ax.set_title(r'$y=cos[2\pi(x+t/t_0)]*cos(2\pi t/t_0)$')x, y = getCosx_t(t=i)y_up = y[np.where(y>0)]x_up = x[np.where(y>0)]x_dn = x[np.where(y<0)]y_dn = y[np.where(y<0)]ax.plot(x, y)ax.hlines(y=0.0, xmin=0.0, xmax=1.0, linestyles='dashed', colors='grey')ax.fill_between(x=x_up, y1=y_up, y2=0, color='red', alpha=0.3)ax.fill_between(x=x_dn, y1=y_dn, y2=0, color='green', alpha=0.3)ax.text(x=0.8, y=0.75, s='t={}'.format(i), fontsize=16, fontfamily='cursive')fig.show(False)fig.savefig('./fig/{}.jpg'.format(i))plt.close(fig)
getFigrues(fig_count) ### 读取图片尺寸
def GetFigSize(fig_path='./fig/0.jpg'):now_img = mimg.imread(fname=fig_path)img_pxy = now_img.shapereturn img_pxy[1], img_pxy[0]### 绘图初始化
img_px, img_py = GetFigSize()
img_dpi=100
fig, ax = plt.subplots(figsize=[img_px/img_dpi, img_py/img_dpi], dpi=img_dpi)
ax.set_aspect('equal')
ax.set_position([0.0, 0.0, 1.0, 1.0])
ax.set_axis_off()
plot_img = ax.imshow(X=np.zeros((img_py, img_px, 3)))### 定义动画更新函数
def UpdateImages(num, f_plot_img):now_img_path = './fig/{}.jpg'.format(num)now_img = mimg.imread(fname=now_img_path)f_plot_img.set_data(now_img)return [f_plot_img]### 创建FunAnimation对象
ani = FuncAnimation(fig, partial(UpdateImages, f_plot_img=plot_img),np.arange(fig_count),blit=True)### 保存动态图片
ani.save('cosxt.gif', fps=60)  

得到的动态图片:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/5869.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NOSQL——redis的安装,配置与简单操作

目录 一、缓存的相关知识 1&#xff09;缓存的概念 2&#xff09;系统缓存 buffer与cache&#xff1a; 3&#xff09;缓存保存位置及分层结构 DNS缓存 应用层缓存 数据层缓存 分布式缓存服务&#xff1a; 数据库&#xff1a; 硬件缓存 二、关系型数据与非关系型数据…

day1-若依项目前后端分离的初步使用

响应式布局: 做好的产品能在pc端,手机,平板都能正常浏览 开发项目两种方式 1.自己从0开始写代码 2.在若依中下载拥有基础功能的源码 若依使用的mysql版本 mysql5.7 导入别人的项目如何操作 若依项目下载地址**:https://gitee.com/y_project/RuoYi-Vue.git** 可以使用揉…

【elementplus】body设置zoom后,el-table开启show-overflow-tooltip后,表格的tooltip显示会错位的解决方案

由于我的项目是无法避免使用zoom&#xff0c;所以只记录zoom后的解决方案 示例&#xff1a;明明划过的是第一行&#xff0c;tooltip却显示到了第四行的位置&#xff1b; 正确显示&#xff1a;划过第一行&#xff0c;tooltip显示在第一行的位置 代码&#xff1a;使用transfor…

Linux--用户身份切换: su

①普通用户切换成超级用户且更改路径&#xff1a;su - ②普通用户切换成超级用户且不更改路径&#xff1a;su root 或者 su ③(由普通用户切换来的)超级用户切换回普通用户&#xff1a;Ctrld ④超级用户切换成普通用户&#xff1a;su 普通用户名 ⑤普通用户a切换成普通用户b…

Java框架学习(二)SSM体系:Spring、SpringMVC、MybatisPlus

文章目录 SpringIoC控制反转DI 依赖注入BeanBean基础配置namescope Bean实例化方式Bean的生命周期 依赖注入方式依赖自动装配 Mybatis-Plus配置BaseMapper通用Service常用注解TableNameTableId雪花算法 TableFieldTableLogic 条件构造器和常用接口QueryWrapperUpdateWrapper 插…

第五节 利用Ogre 2.3实现雨,雪,爆炸,飞机喷气尾焰等粒子效果

本节主要学习如何使用Ogre2.3加载粒子效果。为了学习方便&#xff0c;直接将官方粒子模块Sample_ParticleFX单独拿出来编译&#xff0c;学习如何实现粒子效果。 一. 前提须知 如果参考官方示例建议用最新版的Ogre 2.3.1。否则找不到有粒子效果的示例。不要用官网Ogre2.3 scri…

《项目实战》 Jenkins 与 CICD、发布脚本

文章目录 在这里插入图片描述 前言1、CI/CD是什么&#xff1f;1.1、CI1.2、CD 2、jenkins的下载与安装2.1、下载2.2、安装 3、创建Java Springboot项目3.1、创建项目shell3.2、配置Maven3.3、查看项目shell结构3.4、在启动类增加日志3.4.1、创建ShellController&#xff0c;方便…

如何校验 MySQLOracle 时间字段合规性?

背景信息 在数据迁移或者数据库低版本升级到高版本过程中&#xff0c;经常会遇到一些由于低版本数据库参数设置过于宽松&#xff0c;导致插入的时间数据不符合规范的情况而触发报错&#xff0c;每次报错再发现处理起来较为麻烦&#xff0c;是否有提前发现这类不规范数据的方法&…

【机器学习】基于t-SNE数据可视化工程

一、说明 t-SNE (t-Distributed Stochastic Neighbor Embedding)是一种常用的非线性降维技术。它可以将高维数据映射到一个低维空间(通常是2D或3D)来便于可视化。Scikit-learn API提供TSNE类,以使用T-SNE方法可视化数据。在本教程中,我们将简要学习如何在 Python 中使用 TS…

element 日期选择器下拉框被覆盖

解决&#xff1a;在对应下拉框el-select 标签 添加calss属性即可。此方法不仅适用于日期下拉框&#xff0c;适用于所有下拉框 class"dropdownbox" .dropdownbox{ z-index: 10001 !important; } 图片来自&#xff1a;element ui 时间筛选样式遮盖问题修复_代码搬运媛…

GO富集绘图绘制方法,零基础教程,替换数据直接作图,完成版R语言脚本

速绘 丨 GO富集气泡图 本期分享一个快速绘制GO富集结果图的方法&#xff0c;主要使用R语言tidyverse包&#xff0c;只需导入数据即可一步出图&#xff0c;可以自定义显示的数目、颜色、筛选参数&#xff0c;从此以后绘制GO富集图只需1秒。 前言介绍 下面是一个GO富集分析的结…

【C++11】lambda表达式详解

目录 1.lambda引入 2.语法 3.捕捉列表详解 [ ] 不捕获任何外部变量 [] 捕获父作用域的所有变量的值&#xff0c;只读不可以修改 [&]捕获父作用域的所有变量的引用&#xff0c;可修改捕获的变量 [val] 只捕获指定的变量值&#xff0c;不可以修改 [&val] 只捕获外…