热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Matplotlib保存Python动态图像为视频文件的方法与技巧

本文介绍了如何利用`matplotlib`库中的`FuncAnimation`类将Python中的动态图像保存为视频文件。通过详细解释`FuncAnimation`类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。

FuncAnimation类

class matplotlib.animation.FuncAnimation(

fig, func, frames=None, init_func=None,

fargs=None, save_count=None, **kwargs)

参数

fig : matplotlib.figure.Figure对象,可以理解为画布

func : 函数(callable),每一帧被调用一次

函数签名大概是这样的:def func(frame, *fargs) -> iterable_of_artists

第一个参数是frames中的元素,第二个是fargs参数设置的附件参数

返回值是可迭代的图形对象

frames : 可迭代对象, 整数, 生成函数或者None,传递给动画函数func的帧

如果是可迭代对象,可迭代对象的长度将覆盖save_count参数

如果是个整数,值就是range(frames)

如果是生成函数,签名必须是def gen_function() -> obj:

如果是None,frames=itertools.count,相当于整数从0开始步长1无限迭代

init_func : 函数(callable)

用来画一个完整的帧,如果没有给,使用的是frames中的第一个元素,在第一帧之前被调用

如果If blit == True, init_func 必须返回一个可迭代的图形对象

签名像:def init_func() -> iterable_of_artists:

fargs : 元组或None,每一次调用func的附加参数

save_count : 整数,缓存的帧的数量

interval : number, 2帧之间的延迟,默认200毫秒

repeat_delay : number, 重复延迟,默认None

repeat : bool, 是否重复,默认True

blit : bool, 是否使用blitting优化,默认False

blitting的含义是内存中图像的位块传输,指的是将某一表面的全部或部分图像复制到另一表面上

动图存储配置

# print matplotlib.matplotlib_fname()

# matplotlib\mpl-data\matplotlibrc

animation.writer : ffmpeg ## MovieWriter 使用

animation.ffmpeg_path: ffmpeg ## 可执行文件ffmpeg路径,会搜索$PATH

animation.convert_path: magick ## 可执行文件magick路径,会搜索$PATH

animation.convert_args: convert ## 执行magick的附件参数,因为新ImageMagick的没有convert命令了,所以使用的是convert参数

要保存动图和视频需要使用ImageMagick,后面有下载链接,下载安装之后的目录大概如下:

下载页面:

sin实例

# -*- coding:utf-8 -*-

import numpy as np

from matplotlib import pyplot as plt

from matplotlib import animation

import matplotlib

# print matplotlib.matplotlib_fname()

fig = plt.figure()

ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))

line, = ax.plot([], [], lw=2)

def init():

line.set_data([], [])

return line,

def animate(i):

#linespace(起始值(start),终止值(stop),数量(num)=50,是否包含终止值(endpoint)=True,是否返回步长(retstep)=False,数据类型(dtype)=None)

x = np.linspace(0, 2, 1000)

y = np.sin(2 * np.pi * (x - 0.01 * i))

line.set_data(x, y)

return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,frames=200, interval=20, blit=True)

anim.save('sin.gif', fps=75, writer='imagemagick')

plt.show()

circle实例

# -*- coding:utf-8 -*-

import numpy as np

import matplotlib.pyplot as plt

import matplotlib.animation as animation

import matplotlib.path as mpath

import matplotlib.patches as mpatch

from matplotlib.patches import Circle

import random

fig,ax = plt.subplots()

ax.set_xticks([])

ax.set_yticks([])

ax.spines["left"].set_color("none")

ax.spines["top"].set_color("none")

ax.spines["right"].set_color("none")

ax.spines["bottom"].set_color("none")

ax.axis([-5,5,-5,5])

# ax.add_patch(mpatch.PathPatch(mpath.Path.circle()))

circle = Circle(xy = (0.0, 0.0), radius=0.5, alpha=0.5)

ax.add_patch(circle)

def init():

return Circle(xy = (0.0, 0.0), radius=0.5, alpha=0.5),

def animate(i):

circle.set_radius(i*0.5)

circle.set_facecolor(random.choice("rmcky"))

return circle,

# fig = plt.gcf()

# fg = range(1,11)

# fgr = range(1,11)

# fgr.reverse()

# fs = fg + fgr

fs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

ani = animation.FuncAnimation(fig, animate, init_func=init,frames=fs,interval=1000, blit=True)

# ani = animation.FuncAnimation(fig, animate, frames=360, init_func=init, interval=0.1, blit=True, save_count=50)

# ani = animation.FuncAnimation(fig, animate, frames=10, init_func=init, interval=0.1, blit=True, save_count=50,repeat=False)

ani.save('circle.gif', fps=2, writer='imagemagick')

plt.show()

rain实例

# -*- coding:utf-8 -*-

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.animation import FuncAnimation

# Fixing random state for reproducibility

np.random.seed(19680801)

# Create new Figure and an Axes which fills it.

fig = plt.figure(figsize=(7, 7))

ax = fig.add_axes([0, 0, 1, 1], frameon=False)

ax.set_xlim(0, 1), ax.set_xticks([])

ax.set_ylim(0, 1), ax.set_yticks([])

# Create rain data

n_drops = 50

rain_drops = np.zeros(n_drops, dtype=[('position', float, 2),

('size', float, 1),

('growth', float, 1),

('color', float, 4)])

# Initialize the raindrops in random positions and with

# random growth rates.

rain_drops['position'] = np.random.uniform(0, 1, (n_drops, 2))

rain_drops['growth'] = np.random.uniform(50, 200, n_drops)

# Construct the scatter which we will update during animation

# as the raindrops develop.

scat = ax.scatter(rain_drops['position'][:, 0], rain_drops['position'][:, 1],

s=rain_drops['size'], lw=0.5, edgecolors=rain_drops['color'],

facecolors='none')

def update(frame_number):

# Get an index which we can use to re-spawn the oldest raindrop.

current_index = frame_number % n_drops

# Make all colors more transparent as time progresses.

rain_drops['color'][:, 3] -= 1.0/len(rain_drops)

rain_drops['color'][:, 3] = np.clip(rain_drops['color'][:, 3], 0, 1)

# Make all circles bigger.

rain_drops['size'] += rain_drops['growth']

# Pick a new position for oldest rain drop, resetting its size,

# color and growth factor.

rain_drops['position'][current_index] = np.random.uniform(0, 1, 2)

rain_drops['size'][current_index] = 5

rain_drops['color'][current_index] = (0, 0, 0, 1)

rain_drops['growth'][current_index] = np.random.uniform(50, 200)

# Update the scatter collection, with the new colors, sizes and positions.

scat.set_edgecolors(rain_drops['color'])

scat.set_sizes(rain_drops['size'])

scat.set_offsets(rain_drops['position'])

# Construct the animation, using the update function as the animation director.

animation = FuncAnimation(fig, update, interval=10)

animation.save('rain.gif', fps=75, writer='imagemagick')

plt.show()

保存为mp4

# -*- coding:utf-8 -*-

import numpy as np

import matplotlib

matplotlib.use("Agg")

import matplotlib.pyplot as plt

from matplotlib.animation import FFMpegWriter

# Fixing random state for reproducibility

np.random.seed(19680801)

metadata = dict(title='Movie Test', artist='Matplotlib',comment='Movie support!')

writer = FFMpegWriter(fps=15, metadata=metadata)

fig = plt.figure()

l, = plt.plot([], [], 'k-o')

plt.xlim(-5, 5)

plt.ylim(-5, 5)

x0, y0 = 0, 0

with writer.saving(fig, "writer_test.mp4", 100):

for i in range(100):

x0 += 0.1 * np.random.randn()

y0 += 0.1 * np.random.randn()

l.set_data(x0, y0)

writer.grab_frame()

画心型mp4

# -*- coding:utf-8 -*-

import numpy as np

import matplotlib

matplotlib.use("Agg")

import matplotlib.pyplot as plt

from matplotlib.animation import FFMpegWriter

import math

metadata = dict(title='heart', artist='Matplotlib',comment='draw heart')

writer = FFMpegWriter(fps=15, metadata=metadata)

figure = plt.figure()

axes = plt.gca()

axes.set_xticks([])

axes.set_yticks([])

axes.spines["left"].set_color("none")

axes.spines["top"].set_color("none")

axes.spines["right"].set_color("none")

axes.spines["bottom"].set_color("none")

line1, = axes.plot([], [], color='red', linewidth=2,)

line2, = axes.plot([], [], color='red', linewidth=2,)

plt.xlim(-5, 5)

plt.ylim(-5, 5)

x0, y0 = 0, 0

with writer.saving(figure, "heart.mp4", 100):

for i in range(15):

t = np.linspace(0, i/math.pi, 100)

x = np.sin(t)

y = np.cos(t) + np.power(x, 2.0/3)

line1.set_data(x, y)

line2.set_data(-x, y)

writer.grab_frame()

视频没有办法上传,如果感兴趣可以自己尝试一下。

参考



推荐阅读
  • java文本编辑器,java文本编辑器设计思路
    java文本编辑器,java文本编辑器设计思路 ... [详细]
  • 本文介绍了SVD(奇异值分解)和QR分解的基本原理及其在Python中的实现方法。通过具体代码示例,展示了如何使用这两种矩阵分解技术处理图像数据和计算特征值。 ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • 深入浅出TensorFlow数据读写机制
    本文详细介绍TensorFlow中的数据读写操作,包括TFRecord文件的创建与读取,以及数据集(dataset)的相关概念和使用方法。 ... [详细]
  • 本文介绍了如何利用Python进行批量图片尺寸调整,包括放大和等比例缩放。文中提供了详细的代码示例,并解释了每个步骤的具体实现方法。 ... [详细]
  • 社交网络中的级联行为 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文探讨了为何相同的HTTP请求在两台不同操作系统(Windows与Ubuntu)的机器上会分别返回200 OK和429 Too Many Requests的状态码。我们将分析代码、环境差异及可能的影响因素。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • Python 工具推荐 | PyHubWeekly 第二十一期:提升命令行体验的五大工具
    本期 PyHubWeekly 为大家精选了 GitHub 上五个优秀的 Python 工具,涵盖金融数据可视化、终端美化、国际化支持、图像增强和远程 Shell 环境配置。欢迎关注并参与项目。 ... [详细]
  • 本文详细介绍了 Python 中的条件语句和循环结构。主要内容包括:1. 分支语句(if...elif...else);2. 循环语句(for, while 及嵌套循环);3. 控制循环的语句(break, continue, else)。通过具体示例,帮助读者更好地理解和应用这些语句。 ... [详细]
  • 本文探讨了如何利用HTML5和JavaScript在浏览器中进行本地文件的读取和写入操作,并介绍了获取本地文件路径的方法。HTML5提供了一系列API,使得这些操作变得更加简便和安全。 ... [详细]
  • 二维几何变换矩阵解析
    本文详细介绍了二维平面上的三种常见几何变换:平移、缩放和旋转。通过引入齐次坐标系,使得这些变换可以通过统一的矩阵乘法实现,从而简化了计算过程。文中不仅提供了理论推导,还附有Python代码示例,帮助读者更好地理解这些概念。 ... [详细]
author-avatar
孙孟兰_580
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有