Python Matplotlib绘制动画的代码详解


Posted in Python onMay 30, 2022

matplotlib 动画

我们想制作一个动画,其中正弦和余弦函数在屏幕上逐步绘制。首先需要告诉matplotlib我们想要制作一个动画,然后必须指定想要在每一帧绘制什么。一个常见的错误是重新绘制每一帧的所有内容,这会使整个过程非常缓慢。相反地,只能更新必要的内容,因为我们知道许多内容不会随着帧的变化而改变。对于折线图,我们将使用set_data方法更新绘图,剩下的工作由matplotlib完成。

注意随着动画移动的终点标记。原因是我们在末尾指定了一个标记(markevery=[-1]),这样每次我们设置新数据时,标记就会自动更新并随着动画移动。参见下图。

Python Matplotlib绘制动画的代码详解

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure(figsize=(7, 2))
ax = plt.subplot()

X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
(line1,) = ax.plot(X, C, marker="o", markevery=[-1], 
                   markeredgecolor="white")
(line2,) = ax.plot(X, S, marker="o", markevery=[-1], 
                   markeredgecolor="white")

def update(frame):
    line1.set_data(X[:frame], C[:frame])
    line2.set_data(X[:frame], S[:frame])

plt.tight_layout()
ani = animation.FuncAnimation(fig, update, interval=10)

如果我们现在想要保存这个动画,matplotlib可以创建一个mp4文件,但是选项非常少。一个更好的解决方案是使用外部库,如FFMpeg,它可以在大多数系统上使用。安装完成后,我们可以使用专用的FFMpegWriter,如下图所示:

writer = animation.FFMpegWriter(fps=30)
anim = animation.FuncAnimation(fig, update, 
                               interval=10,
                               frames=len(X))
anim.save("sine-cosine.mp4", writer=writer, dpi=100)

注意,当我们保存mp4动画时,动画不会立即开始,因为实际上有一个与影片创建相对应的延迟。对于正弦和余弦,延迟相当短,可以忽略。但对于长且复杂的动画,这种延迟会变得非常重要,因此有必要跟踪其进展。因此我们使用tqdm库添加一些信息。

from tqdm.autonotebook import tqdm
bar = tqdm(total=len(X)) 
anim.save("../data/sine-cosine.mp4", 
          writer=writer, dpi=300,
          progress_callback = lambda i, n: bar.update(1)) 
bar.close()

Python Matplotlib绘制动画的代码详解

Python Matplotlib绘制动画的代码详解

[Errno 2] No such file or directory: 'ffmpeg'

如果你在 macOS 上,只需通过 homebrew 安装它:brew install ffmpeg

人口出生率

Python Matplotlib绘制动画的代码详解

x = data['指标'].values
rate= data['人口出生率(‰)']
y = rate.values
xvals = np.linspace(2002,2021,1000)
yinterp = np.interp(xvals,x,y)
(line1,) = ax.plot(xvals, yinterp, marker="o", 
                   markevery=[-1], markeredgecolor="white")
text = ax.text(0.01, 0.95,'text', ha="left", va="top", 
               transform=ax.transAxes, size=25)
ax.set_xticks(x)

def update(frame):
    line1.set_data(xvals[:frame], yinterp[:frame])
    text.set_text("%d 年人口出生率(‰) " % int(xvals[frame]))
    return line1, text

男女人口总数

Python Matplotlib绘制动画的代码详解

# 设置画布
fig = plt.figure(figsize=(10, 5))
ax = plt.subplot()
# 数据准备
X = data['指标']
male, female =data['男性人口(万人)'], data['女性人口(万人)']
# 绘制折线图
(line1,) = ax.plot(X, male, marker="o", 
                   markevery=[-1], markeredgecolor="white")
(line2,) = ax.plot(X, female, marker="o", 
                   markevery=[-1], markeredgecolor="white")
# 设置图形注释
text = ax.text(0.01, 0.75,'text', 
               ha="left", va="top", 
               transform=ax.transAxes,size=20)
text2 = ax.text(X[0],male[0], '', ha="left", va="top")
text3 = ax.text(X[0],female[0], '', ha="left", va="top")
# 设置坐标轴刻度标签
ax.set_xticks(X)
ax.set_yticks([])
# 设置坐标轴线格式
ax.spines["top"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["right"].set_visible(False)
# 定义更新函数
def update(frame):
    line1.set_data(X[:frame+1], male[:frame+1])
    line2.set_data(X[:frame+1], female[:frame+1])
    text.set_text("%d 人口(万人)" % X[frame])
    text2.set_position((X[frame], male[frame]))
    text2.set_text(f'男性: {male[frame]}')
    text3.set_position((X[frame], female[frame]))
    text3.set_text(f'女性: {female[frame]}')
    return line1,line2, text
# 定义输出
plt.tight_layout()
writer = animation.FFMpegWriter(fps=5)
# 执行动画
anim = animation.FuncAnimation(fig, update, interval=500, frames=len(X))
# 存储动画
# 设置进度条
bar = tqdm(total=len(X))
anim.save(
    "num_people2.mp4",
    writer=writer,
    dpi=300,
    progress_callback=lambda i, n: bar.update(1),
)
# 关闭进度条
bar.close()

雨滴

Python Matplotlib绘制动画的代码详解

# 设置雨滴绘图更新函数
def rain_update(frame):
    global R, scatter
  # 数据获取
    R["color"][:, 3] = np.maximum(0, R["color"][:, 3] - 1 / len(R))
    R["size"] += 1 / len(R)

    i = frame % len(R)
    R["position"][i] = np.random.uniform(0, 1, 2)
    R["size"][i] = 0
    R["color"][i, 3] = 1
    # 散点形状设置
    scatter.set_edgecolors(R["color"])
    scatter.set_sizes(1000 * R["size"].ravel())
    scatter.set_offsets(R["position"])
    return (scatter,)
# 绘制画布
fig = plt.figure(figsize=(6, 8), facecolor="white", dpi=300)
ax = fig.add_axes([0, 0, 1, 1], frameon=False)  # , aspect=1)
# 绘制初始化散点图
scatter = ax.scatter([], [], s=[], 
                     linewidth=0.5, edgecolors=[], 
                     facecolors="None",cmap='rainbow')
# 设置雨滴数量
n = 250
# 为雨滴设置参数值
R = np.zeros(
    n, dtype=[("position", float, (2,)), 
              ("size", float, (1,)),
              ("color", float, (4,))])
R["position"] = np.random.uniform(0, 1, (n, 2))
R["size"] = np.linspace(0, 1.5, n).reshape(n, 1)
R["color"][:, 3] = np.linspace(0, 1, n)
# 设置坐标轴格式
ax.set_xlim(0, 1), ax.set_xticks([])
ax.set_ylim(0, 1), ax.set_yticks([])
# 保存同上

以上就是Python Matplotlib绘制动画的代码详解的详细内容!


Tags in this post...

Python 相关文章推荐
Python读取图片EXIF信息类库介绍和使用实例
Jul 10 Python
使用Python的web.py框架实现类似Django的ORM查询的教程
May 02 Python
python实现报表自动化详解
Nov 16 Python
浅谈flask中的before_request与after_request
Jan 20 Python
Python爬虫实现百度图片自动下载
Feb 04 Python
python ddt实现数据驱动
Mar 14 Python
浅谈pytorch和Numpy的区别以及相互转换方法
Jul 26 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
Oct 09 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
Jun 01 Python
Python3内置函数chr和ord实现进制转换
Jun 05 Python
python读取excel进行遍历/xlrd模块操作
Jul 12 Python
Python 虚拟环境工作原理解析
Dec 24 Python
关于pytest结合csv模块实现csv格式的数据驱动问题
May 30 #Python
Python中的协程(Coroutine)操作模块(greenlet、gevent)
May 30 #Python
Pandas实现批量拆分与合并Excel的示例代码
May 30 #Python
Python实现仓库管理系统
May 30 #Python
python单向链表实例详解
May 25 #Python
利用Python实现模拟登录知乎
May 25 #Python
python双向链表实例详解
May 25 #Python
You might like
浅析PHP中的UNICODE 编码与解码
2013/06/29 PHP
PHP中include与require使用方法区别详解
2013/10/19 PHP
php修改指定文件后缀的方法
2014/09/11 PHP
使用Git实现Laravel项目的自动化部署
2019/11/24 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
使用TextRange获取输入框中光标的位
2006/10/14 Javascript
JavaScript 事件系统
2010/07/22 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
jQuery简单实现图片预加载
2015/04/20 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
js实现可折叠展开的手风琴菜单效果
2015/09/07 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
浅谈AngularJS中ng-class的使用方法
2016/11/11 Javascript
Nodejs之http的表单提交
2017/07/07 NodeJs
layui中使用jquery控制radio选中事件的示例代码
2018/08/15 jQuery
vue侧边栏动态生成下级菜单的方法
2018/09/07 Javascript
Vue基于vuex、axios拦截器实现loading效果及axios的安装配置
2019/04/26 Javascript
从零搭一个自用的前端脚手架的方法步骤
2019/09/23 Javascript
微信小程序wxml列表渲染原理解析
2019/11/27 Javascript
vue props default Array或是Object的正确写法说明
2020/07/30 Javascript
antd日期选择器禁止选择当天之前的时间操作
2020/10/29 Javascript
python实现360的字符显示界面
2014/02/21 Python
详解Python的单元测试
2015/04/28 Python
Python优化技巧之利用ctypes提高执行速度
2016/09/11 Python
python爬虫实战之最简单的网页爬虫教程
2017/08/13 Python
用python写扫雷游戏实例代码分享
2018/05/27 Python
使用tensorflow实现线性回归
2018/09/08 Python
python实现抠图给证件照换背景源码
2019/08/20 Python
简单了解python列表和元组的区别
2020/05/14 Python
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
SQL注入攻击的种类有哪些
2013/12/30 面试题
部队反四风对照检查材料
2014/09/26 职场文书
诉讼授权委托书
2014/10/15 职场文书
工作自我评价范文
2015/03/05 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript