matplotlib的動畫一直是一個強大但使用頻率不高的功能,究其原因,一方面展示動畫需要一定的媒介,沒有圖形和文字展示方便;二來大家更關心的是分析結果的最終圖表,圖表的動態展示則沒有那麼重要。 不過,隨著短視頻的興起,在短視頻平臺上展示動畫變得非常容易,所以,我們發現有越來越多的數據分析動畫(比如 ...
matplotlib
的動畫一直是一個強大但使用頻率不高的功能,究其原因,
一方面展示動畫需要一定的媒介,沒有圖形和文字展示方便;
二來大家更關心的是分析結果的最終圖表,圖表的動態展示則沒有那麼重要。
不過,隨著短視頻的興起,在短視頻平臺上展示動畫變得非常容易,
所以,我們發現有越來越多的數據分析動畫(比如各種橫向條形圖的排名等等)出現在了短視頻平臺上。
通過動畫來展示數據和模型的變化過程,可使數據的可視化更加生動形象,
隨著各種平臺的興起,matplotlib
的動畫功能也因此有了更多的用武之地。
1. 動畫示例
介紹matplotlib
的動畫功能之前,先看用matplotlib
製作的兩個簡單的的動畫示例。
1.1. 單個動畫
首先是單個動畫,繪製一個正弦曲線。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(-8, 8, 100)
y = np.sin(x)
fig, ax = plt.subplots()
(g,) = ax.plot(x, y)
def update(frame):
y = np.sin(x[:frame])
g.set_data(x[:frame], y)
animation.FuncAnimation(fig, update, interval=50, frames=len(x))
1.2. 組合動畫
除了單個動畫之外,組合動畫也簡單,下麵的示例中,
先繪製一個正弦曲線,然後一個點沿著曲線運動,隨著這個點,繪製正弦曲線的切線。
x = np.linspace(-8, 8, 100)
f = lambda x: np.sin(x / 2)
fig, ax = plt.subplots()
fig.set_size_inches(8, 4)
ax.plot(x, f(x), 'lightblue')
(point,) = ax.plot(x[0], f(x[0]), "r", alpha=0.4, marker="o")
(line,) = ax.plot([0], [0], "g", linewidth=3)
#繪製切線
def tangent_line(x0, y0):
h = 1e-4
num_min = f(x0 - h)
num_max = f(x0 + h)
k = (num_max - num_min) / (2 * h)
xs = np.linspace(x0 - 0.5, x0 + 0.5, 100)
ys = y0 + k * (xs - x0)
return xs, ys
#移動切點
def move_point(frame):
point.set_data([x[frame]], [f(x[frame])])
xs, ys = tangent_line(x[frame], f(x[frame]))
line.set_data(xs, ys)
animation.FuncAnimation(fig, move_point, interval=50, frames=len(x))
2. 動畫函數
matplotlib
的動畫函數主要有兩種,它們的動畫原理差別很大,
瞭解它們之間的區別,才能根據自己的場景選擇合適的動畫函數。
2.1. FuncAnimation
上一節的示例中使用的就是FuncAnimation
,它的動畫原理是通過回調函數,不斷重繪圖形,已達到動畫的效果。
主要的參數有:
- 畫布:比如上面第一個示例中的
fig
- 回調函數:比如上面第一個示例中的
update
- 調用回調函數的間隔:比如上面第一個示例中的
interval=50
,單位是毫秒 - 調用回調函數的次數:比如上面第一個示例中的
frames=len(x)
簡單來說,也就是FuncAnimation
函數每隔interval
毫秒,調用一次update
,一共調用frames
次。``
2.2. ArtistAnimation
ArtistAnimation
函數的原理則是先準備好每一幀的數據,然後繪製按照一定的時間間隔,
繪製每一幀數據對應的圖像。
比如上面的示例一樣的正弦曲線,用ArtistAnimation
函數繪製的話:
points = np.linspace(-8, 8, 100)
fig, ax = plt.subplots()
frames = []
for i in range(50):
x = points[:i]
y = np.sin(x)
g = ax.plot(x, y)
frames.append(g)
animation.ArtistAnimation(fig, frames, interval=50)
ArtistAnimation
的主要參數:
- 畫布:比如上面示例中的
fig
- 每一幀的數據:比如上面示例中的
frames
- 每一幀的間隔:比如上面示例中的
interval=50
,單位是毫秒
ArtistAnimation
沒有回調函數,只要準備好每一幀的數據,它會按照時間間隔繪製每一幀的數據。
3. 動畫導出
最後,是動畫的導出,常用的兩種格式是MP4
和GIF
。
如果安裝了 ffmpeg
,那麼導出這兩種格式就很簡單了。
3.1. 導出mp4
#前面部分省略。。。
anim = animation.FuncAnimation(fig, update, interval=50, frames=len(x))
anim.save("./output.mp4", writer='ffmpeg')
導出的文件名尾碼 mp4
,則可以導出視頻。
這裡的writer
參數用ffmpeg
。
3.2. 導出GIF
同樣,導出gif
也一樣,文件名的尾碼 gif
即可。
#前面部分省略。。。
anim = animation.FuncAnimation(fig, update, interval=50, frames=len(x))
anim.save("./output.gif", writer='ffmpeg')
當然,也可以不用ffmpeg
,比如,如果安裝了imagemagick
,這裡的writer
也可以用imagemagick
。
#前面部分省略。。。
anim = animation.FuncAnimation(fig, update, interval=50, frames=len(x))
anim.save("./output.gif", writer='imagemagick')