制作图表动画
这篇文章会介绍 matplotlib 的 animation 模组,使用模组中的 FuncAnimation() 方法制作图表动画,文章中会制作散点图 ( 散布图 ) 以及正弦波 ( sin 波 ) 折线图的动画图表。
本篇使用的 Python 版本为 3.7.12,所有范例可使用 Google Colab 实作,不用安装任何软件 ( 参考:使用 Google Colab )
import matplotlib
要进行本篇的范例,必须先加载 matplotlib 函数库的 pyplot 模组,范例将其独立命名为 plt,因为要做动画,所以额外加载 animation 模组。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
使用 FuncAnimation()
FuncAnimation() 方法可以将可迭代的数据,提供给指定的函数执行绘图动作,绘图的函数执行完成后,会产生一个动画的对象,只要再透过 save 的方法,就能将该对象储存为 gif 动画或 mp4 影片,使用方法如下:
ani = animation.FuncAnimation(fig, func, frames, interval, init_func, repeat)
相关参数介绍:
| 参数 | 说明 |
|---|---|
| fig | 绘制动画的图表。 |
| func | 每隔动画中,要执行的函数。 |
| frames | 绘制动画的数据,使用“可迭代的数据”,如果填入单一数字,等同于 range(数字)。 |
| interval | 动画间隔时间,默认 200,单位毫秒。 |
| init_func | 一开始要执行的函数 ( 可用也可不用 )。 |
| repeat | 动画是否重复,默认 True。 |
基本散点图动画
下方的程序码执行,会先产生一个 x 轴和 y 轴范围是 0~10 的图表,接着定义 init 函数作为动画开始的函数,以及定义 run 函数作为每格动画要执行的函数,函数内容使用 scatter 方法,在特定座标位置画上一点,最后执行 animation.FuncAnimation 制作动画,数据直接设定 frames 参数为 10 ( 等同提供 range(10) 的数据 ),完成后就会将图表动画储存为 animation.gif。
如果要使用 Colab 储存图表动画,必须先连动 Colab 和云端硬盘,参考:连动 Google Drive。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots() # 建立單一圖表
ax.set_xlim(0,10) # 設定 x 軸範圍 0~10
ax.set_ylim(0,10) # 設定 y 軸範圍 0~10
def init():
ax.scatter(2, 8) # 一開始要執行的韓式,在 (2,8) 的位置畫點
def run(data):
if data>0:
ax.scatter(data, data) # 如果資料大於 0,就在圖表上畫點
else:
pass
ani = animation.FuncAnimation(fig, run, frames=10, interval=10, init_func=init) # 製作動畫
ani.save('animation.gif', fps=10) # 儲存為 gif
plt.show()
下方的程序码,使用 random 函数库产生 30 个 1~50 的随机座标点,并搭配简单的数学运算,产生一张座标点会不断落下的动画图表 ( 搭配 clear() 方法,每次函数执行时将图表清空 )。
import random
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
ax.set_xlim(0,50) # x 座標範圍設定 0~50
ax.set_ylim(0,50) # y 座標範圍設定 0~50
x = random.choices(range(1, 50),k=30) # 隨機 30 個 1~50 的 x 座標
y = random.choices(range(1, 50),k=30) # 隨機 30 個 1~50 的 y 座標
def init():
ax.scatter(x, y)
def run(data):
ax.clear() # 清空圖表
ax.set_xlim(0,50) # x 座標範圍設定 0~50 ( 避免圖表自動調整 )
ax.set_ylim(0,50) # x 座標範圍設定 0~50
for i, e in enumerate(y):
if e>0:
y[i] = e - 1 # 將 y 的數值不斷減少 1,直到為 0
ax.scatter(x, y)
ani = animation.FuncAnimation(fig, run, frames=30, interval=10, init_func=init)
ani.save('animation.gif', fps=10)
plt.show()
正弦波 ( sin 波 ) 折线图动画
下方的程序码使用 line 变数宣告为折线图对象,每次函数执行时,使用 set_data 方法重新提供这个对象数据,就可以画出正弦波的折线图动画。
import math
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots() # 建立單一圖表
ax.set_xlim(0,20) # x 座標範圍設定 0~20
ax.set_ylim(-1.5,1.5) # y 座標範圍設定 -1.5~1.5
n = [i/5 for i in range(100)] # 使用串列升成式產生 0~20 共 100 筆資料
x, y = [], [] # 設定 x 和 y 變數為空串列
line, = ax.plot(x, y) # 定義 line 變數為折線圖物件 ( 注意 line 後方有逗號 )
def run(data):
x.append(data) # 添加 x 資料點
y.append(math.sin(data)) # 添加 y 資料點
line.set_data(x, y) # 重新設定資料點
ani = animation.FuncAnimation(fig, run, frames=n, interval=30)
ani.save('animation.gif', fps=30)
plt.show()
微信扫码关注
抖音扫码关注