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之深入变量和引用对象
Sep 24 Python
python多重继承实例
Oct 11 Python
Flask入门教程实例:搭建一个静态博客
Mar 27 Python
Python赋值语句后逗号的作用分析
Jun 08 Python
python生成词云的实现方法(推荐)
Jun 13 Python
python排序函数sort()与sorted()的区别
Sep 18 Python
PyQt5实现简单数据标注工具
Mar 18 Python
python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
Apr 18 Python
对python while循环和双重循环的实例详解
Aug 23 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
May 15 Python
Selenium 配置启动项参数的方法
Dec 04 Python
python必学知识之文件操作(建议收藏)
May 30 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
星际争霸 Starcraft 发展史
2020/03/14 星际争霸
使用apache模块rewrite_module (转)
2007/02/14 PHP
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
解析左右值无限分类的实现算法
2013/06/20 PHP
php中函数前加&符号的作用分解
2014/07/08 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
jquery实现省市select下拉框的替换(示例代码)
2014/02/22 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
2015/09/24 Javascript
AngularJS控制器controller正确的通信的方法
2016/01/25 Javascript
JavaScript使用readAsDataURL读取图像文件
2017/05/10 Javascript
EasyUI Datebox 日期验证之开始日期小于结束时间
2017/05/19 Javascript
写给vue新手们的vue渲染页面教程
2017/09/01 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
2019/08/22 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
原生JS与CSS实现软件卸载对话框功能
2019/12/05 Javascript
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
在Apache服务器上同时运行多个Django程序的方法
2015/07/22 Python
python与C互相调用的方法详解
2017/07/14 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
2018/02/03 Python
Python中应该使用%还是format来格式化字符串
2018/09/25 Python
Linux下Pycharm、Anaconda环境配置及使用踩坑
2018/12/19 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
python3中替换python2中cmp函数的实现
2019/08/20 Python
如何用Python进行时间序列分解和预测
2021/03/01 Python
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
P D PAOLA意大利官网:西班牙著名的珠宝首饰品牌
2019/09/24 全球购物
银行营业厅大堂经理岗位职责
2014/01/06 职场文书
大学生个人实习的自我评价
2014/02/15 职场文书
中国好声音华少广告词
2014/03/17 职场文书
教师敬业奉献模范事迹材料
2014/05/18 职场文书
职称评定个人总结
2015/03/05 职场文书
刑事法律意见书
2015/06/04 职场文书
2015年小学远程教育工作总结
2015/07/28 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书
python双向链表实例详解
2022/05/25 Python