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 04 Python
python 读取目录下csv文件并绘制曲线v111的方法
Jul 06 Python
python 除法保留两位小数点的方法
Jul 16 Python
python读csv文件时指定行为表头或无表头的方法
Jun 26 Python
Flask框架学习笔记之使用Flask实现表单开发详解
Aug 12 Python
python实现堆排序的实例讲解
Feb 21 Python
python+opencv边缘提取与各函数参数解析
Mar 09 Python
python微信公众号开发简单流程实现
Mar 09 Python
使用Python将Exception异常错误堆栈信息写入日志文件
Apr 08 Python
浅谈pytorch中的BN层的注意事项
Jun 23 Python
python uuid生成唯一id或str的最简单案例
Jan 13 Python
Python GUI编程之tkinter 关于 ttkbootstrap 的使用详解
Mar 03 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
虫族 ZERG 概述
2020/03/14 星际争霸
html中select语句读取mysql表中内容
2006/10/09 PHP
PHP中=赋值操作符对不同数据类型的不同行为
2011/01/02 PHP
mysql,mysqli,PDO的各自不同介绍
2012/09/19 PHP
php发送邮件的问题详解
2015/06/22 PHP
PHP获取页面执行时间的方法(推荐)
2016/12/10 PHP
ajax调用返回php接口返回json数据的方法(必看篇)
2017/05/05 PHP
PHP正则表达式函数preg_replace用法实例分析
2020/06/04 PHP
css3实现背景模糊的三种方式
2021/03/09 HTML / CSS
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
js 调用百度分享功能
2017/02/27 Javascript
激动人心的 Angular HttpClient的源码解析
2017/07/10 Javascript
详解bootstrap导航栏.nav与.navbar区别
2017/11/23 Javascript
修改UA在PC中访问只能在微信中打开的链接方法
2017/11/27 Javascript
vue 动态改变静态图片以及请求网络图片的实现方法
2018/02/07 Javascript
js统计页面上每个标签的数量实例代码
2018/05/29 Javascript
jQuery创建折叠式菜单
2019/06/15 jQuery
Vue使用NProgress的操作过程解析
2019/10/10 Javascript
Javascript模拟实现new原理解析
2020/03/03 Javascript
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
详解python里使用正则表达式的全匹配功能
2017/10/19 Python
FFT快速傅里叶变换的python实现过程解析
2019/10/21 Python
python3用PyPDF2解析pdf文件,用正则匹配数据方式
2020/05/12 Python
HTML5是什么 HTML5是什么意思 HTML5简介
2012/10/26 HTML / CSS
德国大型的家具商店:Pharao24.de
2016/10/02 全球购物
西班牙香水和化妆品网上商店:Douglas
2017/10/29 全球购物
十佳班主任事迹材料
2014/01/18 职场文书
婚庆公司的创业计划书
2014/01/22 职场文书
水利学院求职自荐书
2014/02/01 职场文书
小学生纪念九一八事变演讲稿
2014/09/14 职场文书
质监局领导班子对照检查材料思想汇报
2014/09/27 职场文书
单位政审意见范文
2015/06/04 职场文书
旅游投诉信范文
2015/07/02 职场文书
《刷子李》教学反思
2016/02/20 职场文书
解决vue-router的beforeRouteUpdate不能触发
2022/04/14 Vue.js
springcloud整合seata
2022/05/20 Java/Android