上次尝试了用matplotlib.animation.ArtistAnimation
绘制摆线,实际上也可以用matplotlib.animation.FuncAnimation
实现同样的功能。
导入相关文件
引用的库包括numpy
,matplotlib
,代码如下:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
配置ffmpeg和imagemagick
动图会保存为.gif
和.mp4
两种格式,需要用到这两个库
# Config the ffmpeg_path
plt.rcParams['animation.ffmpeg_path'] = r'D:\Data\software\programming\ffmpeg\ffmpeg-7.0.1-full_build\bin\ffmpeg.exe'
# Config the ImageMagick path with convert_path
plt.rcParams['animation.convert_path'] = r'D:\Data\software\programming\ImageMagick\ImageMagick-7.1.1-33-portable-Q16-HDRI-x64\convert.exe'
animation.FuncAnimation介绍
通过以下命令,可以查看这个方法:
可见,该方法第一个参数是绘图句柄fig
,第二个参数是绘制函数func
,第三个参数是像素帧frames
。
animation.FuncAnimation?
Init signature:
animation.FuncAnimation(
fig,
func,
frames=None,
init_func=None,
fargs=None,
save_count=None,
*,
cache_frame_data=True,
**kwargs,
)
Docstring:
TimedAnimation
subclass that makes an animation by repeatedly calling
a function func.
… note::
You must store the created Animation in a variable that lives as long
as the animation should run. Otherwise, the Animation object will be
garbage-collected and the animation stops.
Parameters
fig : ~matplotlib.figure.Figure
…
Whether frame data is cached. Disabling cache might be helpful when
frames contain large objects.
File: d:\miniconda3\lib\site-packages\matplotlib\animation.py
Type: type
Subclasses:
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…
animation.FuncAnimation??
Init signature:
animation.FuncAnimation(
fig,
func,
frames=None,
init_func=None,
fargs=None,
save_count=None,
*,
cache_frame_data=True,
**kwargs,
)
Source:
class FuncAnimation(TimedAnimation):
“”"
TimedAnimation
subclass that makes an animation by repeatedly calling
a function func.
.. note::
You must store the created Animation in a variable that lives as long
as the animation should run. Otherwise, the Animation object will be
garbage-collected and the animation stops.
Parameters
…
save_count = _api.deprecate_privatize_attribute("3.7")
File: d:\miniconda3\lib\site-packages\matplotlib\animation.py
Type: type
Subclasses:
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…
定义圆及像素帧方法
- 设置圆的半径
# 圆半径
R = 1
- 定义圆和像素帧(摆线定义)
def circle(a, b, r, num=100):
# (a,b): 圆心坐标
# r: 圆半径
# num: 采样密度,默认100
x, y = [0]*num, [0]*num
for i,theta in enumerate(np.linspace(0,2*np.pi,num)):
x[i] = a + r*np.cos(theta)
y[i] = b + r*np.sin(theta)
return x, y
# 摆线定义
def gen():
for theta in np.linspace(0,4*np.pi,100):
yield R*(theta-np.sin(theta)), R*(1-np.cos(theta)), R*theta
绘制图像
配置图像属性,并为动画绘制作准备。
fig = plt.figure(figsize=(6,3))
ax = fig.add_subplot(111)
ax.set_ylim(0, 3)
ax.set_xlim(0, 15)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_aspect('equal')
ax.grid()
time_text = ax.text(0.05, 0.8, '', transform=ax.transAxes)
cycloid, = ax.plot([], [], 'r-', lw=2)
line, = ax.plot([], [], 'y-', lw=2)
circle_line, = ax.plot([], [], 'g', lw=2)
point, = ax.plot([], [], 'bo', ms=4)
xx, yy = [], []
def func(data):
x, y, Rt = data
time_text.set_text(r'$\theta$ = %.2f $\pi$' % (Rt/np.pi))
xx.append(x)
yy.append(y)
cx, cy = circle(Rt, R, R)
cycloid.set_data(xx, yy)
line.set_data((x,Rt), (y,R))
circle_line.set_data(cx, cy)
point.set_data([x], [y])
创建动画
ani = animation.FuncAnimation(fig, func, frames=gen, blit=False, save_count=100, interval=50)
保存为mp4
和gif
格式
fn = 'cycloid_FuncAnimation_blog'
ani.save('%s.mp4'%(fn), writer='ffmpeg', fps=1000/50)
xx, yy = [], [] # 清空轨迹缓存
ani.save('%s.gif'%(fn), writer='imagemagick', fps=1000/50)
在Jupyter Notebook上显示动画
plt.rcParams['animation.html'] = 'html5'
xx, yy = [], []
ani