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模拟登录百度贴吧(百度贴吧登录)实例
Dec 18 Python
Python判断Abundant Number的方法
Jun 15 Python
python实现根据主机名字获得所有ip地址的方法
Jun 28 Python
Python的shutil模块中文件的复制操作函数详解
Jul 05 Python
Linux 下 Python 实现按任意键退出的实现方法
Sep 25 Python
深入浅析python with语句简介
Apr 11 Python
Flask之请求钩子的实现
Dec 23 Python
解决Django一个表单对应多个按钮的问题
Jul 18 Python
python excel转换csv代码实例
Aug 26 Python
浅谈Pytorch torch.optim优化器个性化的使用
Feb 20 Python
简述 Python 的类和对象
Aug 21 Python
python 用pandas实现数据透视表功能
Dec 21 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
mysql5的sql文件导入到mysql4的方法
2008/10/19 PHP
如何用C语言编写PHP扩展的详解
2013/06/13 PHP
PHP、Nginx、Apache中禁止网页被iframe引用的方法
2020/10/01 PHP
PHP编程获取各个时间段具体时间的方法
2017/05/26 PHP
PHP简单装饰器模式实现与用法示例
2017/06/22 PHP
window.open()弹出居中的窗口
2007/02/01 Javascript
Mootools 1.2教程(2) DOM选择器
2009/09/14 Javascript
JavaScript 格式字符串的应用
2010/03/29 Javascript
详解AngularJS中自定义过滤器
2015/12/28 Javascript
AngularJS基础 ng-value 指令简单示例
2016/08/03 Javascript
手机Web APP如何实现分享多平台功能
2016/08/19 Javascript
jQuery中show与hide方法用法示例
2016/09/16 Javascript
Node.js批量给图片加水印的方法
2016/11/15 Javascript
canvas绘制七巧板
2017/02/03 Javascript
JS实现根据密码长度显示安全条功能
2017/03/08 Javascript
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
解决vue多个路由共用一个页面的问题
2018/03/12 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
2019/09/27 Javascript
Mac中升级Python2.7到Python3.5步骤详解
2017/04/27 Python
Python用 KNN 进行验证码识别的实现方法
2018/02/06 Python
Python语言快速上手学习方法
2018/12/14 Python
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
Python判断对象是否为文件对象(file object)的三种方法示例
2019/04/26 Python
python将时分秒转换成秒的实例
2019/12/07 Python
tensorflow 实现自定义layer并添加到计算图中
2020/02/04 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
详解python3 GUI刷屏器(附源码)
2021/02/18 Python
美国折扣网站:jClub
2017/08/07 全球购物
怎样写留学自荐信
2013/11/11 职场文书
中级会计职业生涯规划书
2014/03/01 职场文书
优秀班组长事迹
2014/05/31 职场文书
光棍节联谊晚会活动策划书
2014/10/10 职场文书
通知函格式范文
2015/04/27 职场文书
会计岗位工作总结
2015/08/12 职场文书
小学科学课教学反思
2016/02/23 职场文书
zabbix配置nginx监控的实现
2022/05/25 Servers