今天分享的這篇譯文中介紹了 matplotlib 繪圖庫的一個 使用示例,即如何制作 GIF 動圖。本文原作者為 Eli Bendersky,譯者為 唐曉霆 Jason ,由編程派 EarlGrey 校對。
譯者簡介:唐曉霆,在香港的成都人,城市大學(xué)研究助理,會寫python,興趣是深度學(xué)習(xí)。
這篇短文介紹如何用 Python 里的 matplotlib 畫出 GIF 動圖。下面的代碼我在一臺安裝了 ImagMagick 的 Ubuntu 機器上運行過。 若想要用 matplotlib 的 save
方法渲染 GIF 動圖的話,就必須安裝 ImageMagick 。
下面給一個動畫樣本:
有幾點需要注意:
圖里的散點部分是不變的;變的是直線
X 軸的標(biāo)題每一幀都在變化
下面上制作該圖的代碼:
import sysimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.animation import FuncAnimationfig, ax = plt.subplots()fig.set_tight_layout(True)# 詢問圖形在屏幕上的尺寸和DPI(每英寸點數(shù))。# 注意當(dāng)我們把圖形儲存成一個文件時,我們需要再另外提供一個DPI值print('fig size: {0} DPI, size in inches {1}'.format(fig.get_dpi(), fig.get_size_inches()))# 畫出一個維持不變(不會被重畫)的散點圖和一開始的那條直線。x = np.arange(0, 20, 0.1)ax.scatter(x, x + np.random.normal(0, 3.0, len(x)))line, = ax.plot(x, x - 5, 'r-', linewidth=2)def update(i):label = 'timestep {0}'.format(i)print(label)# 更新直線和x軸(用一個新的x軸的標(biāo)簽)。# 用元組(Tuple)的形式返回在這一幀要被重新繪圖的物體line.set_ydata(x - 5 + i)ax.set_xlabel(label)return line, axif __name__ == '__main__':# FuncAnimation 會在每一幀都調(diào)用“update” 函數(shù)。# 在這里設(shè)置一個10幀的動畫,每幀之間間隔200毫秒anim = FuncAnimation(fig, update, frames=np.arange(0, 10), interval=200)if len(sys.argv) > 1 and sys.argv[1] == 'save':anim.save('line.gif', dpi=80, writer='imagemagick')else:# plt.show() 會一直循環(huán)播放動畫plt.show()
如果你想換一個更精美的主題,安裝 seaborn 庫之后添加一行:
import seaborn
然后你就會得到這個圖:
提一句關(guān)于文件大小的警告:雖然我在這里分享的GIF只有 10 幀,而且圖像也很簡單,但是它們每一幀都占大約 160K 。就我理解而言,GIF 動圖不使用跨幀壓縮, 所以這使得長一點的 GIF 占的空間異常大。減少幀數(shù)到最最小并且讓每一幀的圖像小一點(通過在 matplotlib 里調(diào)整圖形尺寸或者 DPI ),就可以多多少少幫助緩解一下這個問題。
EarlGrey:我自己測試生成的 line.gif 文件大概 86 KB 左右。