Python?matplotlib包和gif包生成gif動畫實戰(zhàn)對比
前言
使用matplotlib生成gif動畫的方法有很多,一般常規(guī)使用matplotlib的animation模塊的FuncAnimation函數(shù)實現(xiàn)。
在matplotlib官網(wǎng)看到了第三方動畫包gif的介紹。
gif包概述
gif包是支持 Altair, matplotlib和Plotly的動畫擴展。
gif依賴PIL,即pillow,要求Pillow>=7.1.2。
安裝gif包,pip install gif
動畫原理
所有動畫都是由幀(frame)構(gòu)成的,一幀就是一幅靜止的畫面,連續(xù)的幀就形成動畫。我們通常說幀數(shù),簡單地說,就是在1秒鐘時間里傳輸?shù)膱D片的幀數(shù),也可以理解為圖形處理器每秒鐘能夠刷新幾次,通常用fps(Frames Per Second)表示。
制作動畫的關鍵:如何生成幀,每秒多少幀。
gif包解讀
gif包非常簡潔,只有一個單獨的文件gif.py,文件主要包含options類、frames和save兩個函數(shù)。
options類
提供精簡版 的Altair, matplotlib和Plotly的保存或輸出設置。以matplotlib為例,提供以下設置。
- dpi (int): The resolution in dots per inch
- facecolor (colorspec): The facecolor of the figure
- edgecolor (colorspec): The edgecolor of the figure
- transparent (bool): If True, the axes patches will all be transparent
設置方法:gif.options.matplotlib["dpi"] = 300
原理:options在構(gòu)造函數(shù)中創(chuàng)建matplotlib字典保存配置,隨后傳遞給底層的matplotlib包。
frames函數(shù)
裝飾器函數(shù),通過對應包編寫自定義繪圖函數(shù)生成單幀圖像。
save函數(shù)
根據(jù)幀序列生成動畫。
def save(frames, path, duration=100, unit="milliseconds", between="frames", loop=True): """Save decorated frames to an animated gif. - frames (list): collection of frames built with the gif.frame decorator - path (str): filename with relative/absolute path - duration (int/float): time (with reference to unit and between) - unit {"ms" or "milliseconds", "s" or "seconds"}: time unit value - between {"frames", "startend"}: duration between "frames" or the entire gif ("startend") - loop (bool): infinitely loop the animation
frames即根據(jù)@gif.frame裝飾的繪圖函數(shù)生成的幀的序列,此處根據(jù)需要自定義。
duration即持續(xù)時間,由單位unit和模式between決定,默認為frames為幀間的時間間隔。
unit即持續(xù)時間單位,支持毫秒和秒,默認為毫秒。
between即持續(xù)時間計算模式,默認frames即duration為幀之間的時間間隔,startend模式時duration=duration /len(frames),即duration為所有幀—整個動畫的持續(xù)時間。
gif包生成gif動畫實踐
import random from matplotlib import pyplot as plt import gif # 構(gòu)造數(shù)據(jù) x = [random.randint(0, 100) for _ in range(100)] y = [random.randint(0, 100) for _ in range(100)] #設置選項 gif.options.matplotlib["dpi"] = 300 #使用gif.frame裝飾器構(gòu)造繪圖函數(shù),即如何生成靜態(tài)的幀 @gif.frame def plot(i): xi = x[i*10:(i+1)*10] yi = y[i*10:(i+1)*10] plt.scatter(xi, yi) plt.xlim((0, 100)) plt.ylim((0, 100)) # 構(gòu)造幀序列frames,即把生成動畫的所有幀按順序放在列表中 frames = [] for i in range(10): frame = plot(i) frames.append(frame) # 根據(jù)幀序列frames,動畫持續(xù)時間duration,生成gif動畫 gif.save(frames, 'example.gif', duration=3.5, unit="s", between="startend")
以心形曲線為例比較gif包和animation模塊實現(xiàn)動畫的差異
gif包的實現(xiàn)方式
import numpy as np import gif from matplotlib import pyplot as plt t = np.linspace(0, 6, 100) x = 16 * np.sin(t) ** 3 y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t) @gif.frame def plot_love(x, y): plt.figure(figsize=(5, 3), dpi=100) plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$") plt.axis("off") frames = [] for i in range(1, len(x)): of = plot_love(x[:i], y[:i]) frames.append(of) gif.save(frames, "love.gif", duration=80)
matplotlib 常規(guī)FuncAnimation函數(shù)實現(xiàn)方式
from matplotlib import pyplot as plt import matplotlib.animation as animation import numpy as np t = np.linspace(0, 6, 100) x = 16 * np.sin(t) ** 3 y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t) data=[i for i in zip(x,y)] def plot_love(data): x, y = data plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$") fig=plt.figure(figsize=(5, 3), dpi=100) plt.axis("off") animator = animation.FuncAnimation(fig, plot_love, frames=data, interval=80) animator.save("love.gif", writer='pillow')
matplotlib底層PillowWriter類實現(xiàn)方式
from matplotlib import pyplot as plt import matplotlib.animation as animation import numpy as np t = np.linspace(0, 6, 100) x = 16 * np.sin(t) ** 3 y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t) def plot_love(x,y): plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$") fig=plt.figure(figsize=(5, 3), dpi=100) plt.axis("off") writer = animation.PillowWriter(fps=15) with writer.saving(fig, "love1.gif"): for i in range(1, len(x)): of = plot_love(x[i], y[i]) writer.grab_frame()
比較結(jié)果
通過比較可知gif包的實現(xiàn)方式和matplotlib中利用PillowWriter實現(xiàn)方式類似,更偏底層一些,這樣遇到比較復雜的繪圖時更靈活。
總結(jié)
到此這篇關于Python matplotlib包和gif包生成gif動畫實戰(zhàn)對比的文章就介紹到這了,更多相關matplotlib包和gif包生成gif內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python數(shù)據(jù)相關系數(shù)矩陣和熱力圖輕松實現(xiàn)教程
這篇文章主要介紹了Python數(shù)據(jù)相關系數(shù)矩陣和熱力圖輕松實現(xiàn)教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06django文檔學習之a(chǎn)pplications使用詳解
這篇文章主要介紹了Python文檔學習之a(chǎn)pplications使用詳解,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-01-01