如何利用Matplotlib庫繪制動畫及保存GIF圖片
前言
在自學機器學習或者是深度學習的過程中,有的時候總想把執行過程或者執行結果顯示出來,所以就想到瞭動畫。好在用 Python 實現動畫有許多中方式,而大傢熟知的 Matplotlib 庫就可以實現。
本文的目的是對 Matplotlib 的動畫實現手段做一個簡單的說明。
繪制動畫
import matplotlib.pyplot as plt import matplotlib.animation as animation
如果要讓 matplotlib 實現動畫功能的話,那麼就要引入 animation 模塊。
然後再創建 animation 的對象。
anim = animation.FuncAnimation(fig, run, data_gen, blit=False, interval=10, repeat=False, init_func=init)
animation 的實現類是 FuncAnimation,它有一個構造方法。下面先通過一個示例,講解 animation 的基本用法,然後再來細致分析 FuncAnimation 構造方法中各項參數的意義。
我們的目標是做一個 Sin 函數的動畫示例。
代碼很簡單。
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation fig, ax = plt.subplots() xdata, ydata = [], [] ln, = plt.plot([], [], 'ro',animated=True) def init(): ax.set_xlim(-np.pi,np.pi) ax.set_ylim(-1, 1) return ln, def update(frame): xdata.append(frame) ydata.append(np.sin(frame)) ln.set_data(xdata, ydata) return ln, anim = animation.FuncAnimation(fig, update, frames=np.linspace(-np.pi,np.pi, 90),interval=10, init_func=init,blit=True) plt.show()
核心代碼是這一行。
anim = animation.FuncAnimation(fig, update, frames=np.linspace(-np.pi,np.pi, 90),interval=10, init_func=init,blit=True)
按照上面的示例代碼,我們可以依葫蘆畫瓢編寫動畫代碼瞭。
但,如果我們需要達到靈活運用的話,就需要花點心思,瞭解它們的機制。
我們先來看看 FuncAnimation 的構造方法。
def __init__(self, fig, func, frames=None, init_func=None, fargs=None, save_count=None, **kwargs):
fig 自然是 matplotlib 中的 figure 對象。
func 是每一次更新時所調用的方法,它是回調函數。因此,我們可以在這個方法中更新 figure 當中的 axes 中的 line2d 對象,它是動態更新 figure 的根本。
frames 代表瞭整個動畫過程中幀的取值范圍,而本質上是一個數據發生器。我將在後面重點講解它。
init_func 是初始函數,用來初始 figure 的畫面。
fargs 是每次附加給 func 回調函數的參數,可以為 None
save_count 是緩存的數量
除此之外,還有一些可選的參數,它們分別是
interval 是每 2 個 frame 發生的時間間隔,單位是 ms,默認值是 200.
repeat_delay 取值是數值,如果 animation 是重復播放的話,這個值就是每次播放之間的延遲時間,單位是 ms。
repeat bool 型可選參數,默認為 True,代表動畫是否會重復執行
blit bool 型可選參數,控制繪制的優化。默認是 False。
如何理解 animation 呢?
我認為,animation 的核心是 frames 和 func。
frames 可以取值:iterable,int,generator 生成器函數 或者是 None。
在上面的代碼中,我們給 frames 的取值是這樣的。
frames=np.linspace(-np.pi,np.pi, 90)
其實就是一個 list,它的值范圍為 -pi 到 pi,frames 總共有 90 幀,而 list 是一個 iterable 類型,所以它可以不停的迭代。
frames 也可以取值為整數,相當於給參數賦值 range(frames)。
frames 也可以取值為 None,那麼它的結果相當於傳遞 itertools.count,結構就是從 0 開始,每次步進 1,無限的執行下去。
frames 還接受 generator 函數,也就是生成器,但有個前提是,生成器要符合下面的簽名格式。
def gen_function() -> obj
參數列表為空,但需要返回一個值,這個值就會傳入到 func 回調函數當中。
func 是回調函數,它會在每次更新的時候被調用,所以我們隻需要在這個函數中更新 figure 中的數值就可以瞭,就像下面代碼。
def update(frame): xdata.append(frame) ydata.append(np.sin(frame)) ln.set_data(xdata, ydata) return ln,
frames 和 func 的關系是什麼?
實際上,frames 決定瞭整個動畫 frame 的取值范圍,它會在 interval 時間內迭代一次,然後將值傳遞給 func,直到整個 frames 迭代完畢。
我本人而言,也更傾向於用 generator 函數去定義 frames 而不是直接分配一個列表,所以我可以將之前的代碼改寫如下。
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation fig, ax = plt.subplots() xdata, ydata = [], [] ln, = plt.plot([], [], 'ro',animated=True) def init(): ax.set_xlim(-np.pi,np.pi) ax.set_ylim(-1, 1) return ln, def update(frame): xdata.append(frame) ydata.append(np.sin(frame)) ln.set_data(xdata, ydata) return ln, def data_gen(): frame = -np.pi step = 2 * np.pi / 90 while frame < np.pi: frame += step yield frame # anim = animation.FuncAnimation(fig, update, frames=np.linspace(-np.pi,np.pi, 360),interval=10, # init_func=init,blit=True) anim = animation.FuncAnimation(fig, update, frames=data_gen,interval=10, init_func=init,blit=True) plt.show()
data_gen 就是一個生成器函數,它會每隔 10ms 運行一次,然後將結果傳遞給 update 函數。
data_gen 裡面運用到瞭 yield 關鍵字,這是的我們可以在每次迭代時才返回相應的結構,而不要在一開始就分配。如果不熟悉這方面知識點的同學,可以自行搜索相應的知識。
保存動畫
因為經常寫博客,所以也經常需要將結果保存下來,一般我會保存為 .gif 格式圖片,本篇博文的 gif 圖像就是通過 matplotlib 保存的。
好在用 matplotlib 實現它也並不難。
anim.save('test_animation.gif',writer='imagemagick')
一句代碼就搞定瞭,運行成功後,會在當前目錄下生成 test_animation.gif 圖像。
需要註意到的是,如果要保存 gif 圖像,這要求開發者電腦已經安裝瞭 ImageMagicK。
ubuntu 用戶可以通過如下命令安裝。
sudo apt-get install imagemagick
並且,動畫保存的時候要指定 writer 為 imagemagick.
動畫可以保存為 gif 圖像,自然也能保存為 mp4 視頻格式。
但這要求開發者計算機已經安裝好 ffmpeg 庫,並且 save 方法中指定 writer 為 ffmpeg,具體細節請讀者自行擴展閱讀。
總結
到此這篇關於如何利用Matplotlib庫繪制動畫及保存GIF圖片的文章就介紹到這瞭,更多相關Matplotlib庫繪制動畫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python中的圖形繪制簡單動畫實操
- Matplotlib animation模塊實現動態圖
- Python實現動態繪圖的示例詳解
- Python Matplotlib繪制動圖平滑曲線
- Python編程使用matplotlib繪制動態圓錐曲線示例