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 13 Python
python实现二叉查找树实例代码
Feb 08 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
Feb 07 Python
Python数据类型之Dict字典实例详解
May 07 Python
使用Python实现将list中的每一项的首字母大写
Jun 11 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
python编写简单端口扫描器
Sep 04 Python
Python可以实现栈的结构吗
May 27 Python
详解Django中views数据查询使用locals()函数进行优化
Aug 24 Python
python中numpy数组与list相互转换实例方法
Jan 29 Python
pytorch 计算Parameter和FLOP的操作
Mar 04 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
用 javascript 实现的点击复制代码
2007/03/24 Javascript
jQuery EasyUI API 中文文档 - Panel面板
2011/09/30 Javascript
jQuery滚动加载图片效果的实现
2013/03/06 Javascript
推荐一个封装好的getElementsByClassName方法
2014/12/02 Javascript
JS简单实现动画弹出层效果
2015/05/05 Javascript
JQ选择器_选择同类元素的第N个子元素的实现方法
2016/09/08 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
详解使用vue脚手架工具搭建vue-webpack项目
2017/05/10 Javascript
js 简易版滚动条实例(适用于移动端H5开发)
2017/06/26 Javascript
jquery实现用户登陆界面(示例讲解)
2017/09/06 jQuery
vue 父组件给子组件传值子组件给父组件传值的实例代码
2019/04/15 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
2019/05/05 Javascript
react 移动端实现列表左滑删除的示例代码
2019/07/04 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
[01:09]DOTA2次级职业联赛 - ishow.HMM战队宣传片
2014/12/01 DOTA
[02:07]2017国际邀请赛中国区预选赛直邀战队前瞻
2017/06/23 DOTA
[54:28]EG vs OG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python实现自定义函数的5种常见形式分析
2018/06/16 Python
python查看模块安装位置的方法
2018/10/16 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
Python注释、分支结构、循环结构、伪“选择结构”用法实例分析
2020/01/09 Python
python+selenium+Chrome options参数的使用
2020/03/18 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
英国在线发型和美容产品商店:Beauty Cutie
2019/04/27 全球购物
英国女性化妆品收纳和家具网站:Beautify
2019/12/07 全球购物
个人对照检查材料思想汇报(四风问题)
2014/09/25 职场文书
会计师事务所实习证明
2014/11/16 职场文书
食品仓管员岗位职责
2015/04/01 职场文书
教师节晚会主持词
2015/06/30 职场文书
学习弘扬焦裕禄精神心得体会
2016/01/23 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
七年级作文之英语老师
2019/10/28 职场文书
如何用PHP websocket实现网页实时聊天
2021/05/26 PHP
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js
【海涛DOTA解说】EVE女子战队独家录像加ZSMJ神牛两连发
2022/04/01 DOTA