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学习之matplotlib绘制散点图实例
Dec 09 Python
flask框架中勾子函数的使用详解
Aug 01 Python
python使用PIL模块获取图片像素点的方法
Jan 08 Python
python简单验证码识别的实现方法
May 10 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
Jun 24 Python
Python爬虫学习之翻译小程序
Jul 30 Python
在VS2017中用C#调用python脚本的实现
Jul 31 Python
Python进阶之使用selenium爬取淘宝商品信息功能示例
Sep 16 Python
tensorflow使用L2 regularization正则化修正overfitting过拟合方式
May 22 Python
python 引用传递和值传递详解(实参,形参)
Jun 05 Python
一个入门级python爬虫教程详解
Jan 27 Python
python 爬取吉首大学网站成绩单
Jun 02 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数组是否为索引数组的实现方法
2013/06/13 PHP
PHP中Memcache操作类及用法实例
2014/12/12 PHP
PHP7匿名类用法分析
2016/09/26 PHP
jquery 简短几句代码实现给元素动态添加及获取提示信息
2011/09/01 Javascript
jQuery Ajax提交表单查询获得数据实例代码
2012/09/19 Javascript
jQuery中prevAll()方法用法实例
2015/01/08 Javascript
JavaScript原生对象之String对象的属性和方法详解
2015/03/13 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
Jquery中巧用Ajax的beforeSend方法
2016/01/20 Javascript
微信小程序  网络请求API详解
2016/10/25 Javascript
jQuery中值得注意的trigger方法浅析
2016/12/12 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
2017/03/03 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
vue路由传参的基本实现方式小结【三种方式】
2020/02/05 Javascript
Nuxt 嵌套路由nuxt-child组件用法(父子页面组件的传值)
2020/11/05 Javascript
python的random模块及加权随机算法的python实现方法
2017/01/04 Python
详解python之多进程和进程池(Processing库)
2017/06/09 Python
requests和lxml实现爬虫的方法
2017/06/11 Python
python使用turtle库绘制时钟
2020/03/25 Python
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
Python中新式类与经典类的区别详析
2019/07/10 Python
python retrying模块的使用方法详解
2019/09/25 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
Python如何实现爬取B站视频
2020/05/20 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
美国隐形眼镜销售网站:ContactsDirect
2017/10/28 全球购物
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
介绍下Lucene建立索引的过程
2016/03/02 面试题
总经理助理的八要求
2013/11/12 职场文书
教师实习自我鉴定
2013/12/14 职场文书
大课间活动制度
2014/01/18 职场文书
干部作风建设个人剖析材料
2014/10/11 职场文书
超强台风观后感
2015/06/09 职场文书
信息技术课教学反思
2016/02/23 职场文书
个人售房合同协议书
2016/03/21 职场文书