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 getopt 参数处理小示例
Jun 09 Python
Python网络爬虫出现乱码问题的解决方法
Jan 05 Python
详解python的webrtc库实现语音端点检测
May 31 Python
python中闭包Closure函数作为返回值的方法示例
Dec 17 Python
python实现mysql的读写分离及负载均衡
Feb 04 Python
python实现顺序表的简单代码
Sep 28 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
Jan 30 Python
Python-copy()与deepcopy()区别详解
Jul 12 Python
使用Rasterio读取栅格数据的实例讲解
Nov 26 Python
Python图像处理库PIL的ImageDraw模块介绍详解
Feb 26 Python
哈工大自然语言处理工具箱之ltp在windows10下的安装使用教程
May 07 Python
六种酷炫Python运行进度条效果的实现代码
Jul 17 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 strtotime函数详解
2009/12/18 PHP
PHP中的reflection反射机制测试例子
2014/08/05 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
2015/01/26 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
在 Laravel 中动态隐藏 API 字段的方法
2019/10/25 PHP
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
ExtJS 入门
2010/10/29 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
jQuery多级弹出菜单插件ZoneMenu
2014/12/18 Javascript
javascript闭包的理解
2015/04/01 Javascript
jQuery右侧选项卡焦点图片轮播特效代码分享
2015/09/05 Javascript
Bootstrap项目实战之首页内容介绍(全)
2016/04/25 Javascript
浅谈bootstrap源码分析之tab(选项卡)
2016/06/06 Javascript
AngularJS基础 ng-paste 指令简单示例
2016/08/02 Javascript
JS实现模糊查询带下拉匹配效果
2018/06/21 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
关于AOP在JS中的实现与应用详解
2019/05/06 Javascript
JS获取动态添加元素的方法详解
2019/07/31 Javascript
javascript中的数据类型检测方法详解
2019/08/07 Javascript
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
2013/01/17 Python
python实现在控制台输入密码不显示的方法
2015/07/02 Python
python实现ID3决策树算法
2017/12/20 Python
Python实现霍夫圆和椭圆变换代码详解
2018/01/12 Python
pandas pivot_table() 按日期分多列数据的方法
2018/11/16 Python
通过python扫描二维码/条形码并打印数据
2019/11/14 Python
简单了解python filter、map、reduce的区别
2020/01/14 Python
Python 在局部变量域中执行代码
2020/08/07 Python
CSS3中使用RGBa来调节透明度的教程
2016/05/09 HTML / CSS
Big Green Smile德国网上商店:提供各种天然产品
2018/05/23 全球购物
智能家居、吸尘器、滑板车、电动自行车网上购物:Geekmaxi
2021/01/18 全球购物
网络程序员自荐信
2014/01/25 职场文书
青年文明号复核材料
2014/02/11 职场文书
后勤主管岗位职责
2014/03/01 职场文书
合作投资意向书
2014/04/01 职场文书
流动人口婚育证明
2014/10/19 职场文书
2015年班长个人工作总结
2015/04/03 职场文书