Python Matplotlib繪制動畫的代碼詳解
matplotlib 動畫
我們想制作一個動畫,其中正弦和余弦函數(shù)在屏幕上逐步繪制。首先需要告訴matplotlib我們想要制作一個動畫,然后必須指定想要在每一幀繪制什么。一個常見的錯誤是重新繪制每一幀的所有內(nèi)容,這會使整個過程非常緩慢。相反地,只能更新必要的內(nèi)容,因為我們知道許多內(nèi)容不會隨著幀的變化而改變。對于折線圖,我們將使用set_data
方法更新繪圖,剩下的工作由matplotlib完成。
注意隨著動畫移動的終點標(biāo)記。原因是我們在末尾指定了一個標(biāo)記(markevery=[-1]
),這樣每次我們設(shè)置新數(shù)據(jù)時,標(biāo)記就會自動更新并隨著動畫移動。參見下圖。
import?numpy?as?np import?matplotlib.pyplot?as?plt import?matplotlib.animation?as?animation fig?=?plt.figure(figsize=(7,?2)) ax?=?plt.subplot() X?=?np.linspace(-np.pi,?np.pi,?256,?endpoint=True) C,?S?=?np.cos(X),?np.sin(X) (line1,)?=?ax.plot(X,?C,?marker="o",?markevery=[-1],? ???????????????????markeredgecolor="white") (line2,)?=?ax.plot(X,?S,?marker="o",?markevery=[-1],? ???????????????????markeredgecolor="white") def?update(frame): ????line1.set_data(X[:frame],?C[:frame]) ????line2.set_data(X[:frame],?S[:frame]) plt.tight_layout() ani?=?animation.FuncAnimation(fig,?update,?interval=10)
如果我們現(xiàn)在想要保存這個動畫,matplotlib可以創(chuàng)建一個mp4文件,但是選項非常少。一個更好的解決方案是使用外部庫,如FFMpeg,它可以在大多數(shù)系統(tǒng)上使用。安裝完成后,我們可以使用專用的FFMpegWriter,如下圖所示:
writer?=?animation.FFMpegWriter(fps=30) anim?=?animation.FuncAnimation(fig,?update,? ???????????????????????????????interval=10, ???????????????????????????????frames=len(X)) anim.save("sine-cosine.mp4",?writer=writer,?dpi=100)
注意,當(dāng)我們保存mp4動畫時,動畫不會立即開始,因為實際上有一個與影片創(chuàng)建相對應(yīng)的延遲。對于正弦和余弦,延遲相當(dāng)短,可以忽略。但對于長且復(fù)雜的動畫,這種延遲會變得非常重要,因此有必要跟蹤其進(jìn)展。因此我們使用tqdm
庫添加一些信息。
from?tqdm.autonotebook?import?tqdm bar?=?tqdm(total=len(X))? anim.save("../data/sine-cosine.mp4",? ??????????writer=writer,?dpi=300, ??????????progress_callback?=?lambda?i,?n:?bar.update(1))? bar.close()
[Errno 2] No such file or directory: 'ffmpeg'
如果你在 macOS 上,只需通過 homebrew 安裝它:brew install ffmpeg
人口出生率
x?=?data['指標(biāo)'].values rate=?data['人口出生率(‰)'] y?=?rate.values xvals?=?np.linspace(2002,2021,1000) yinterp?=?np.interp(xvals,x,y) (line1,)?=?ax.plot(xvals,?yinterp,?marker="o",? ???????????????????markevery=[-1],?markeredgecolor="white") text?=?ax.text(0.01,?0.95,'text',?ha="left",?va="top",? ???????????????transform=ax.transAxes,?size=25) ax.set_xticks(x) def?update(frame): ????line1.set_data(xvals[:frame],?yinterp[:frame]) ????text.set_text("%d?年人口出生率(‰)?"?%?int(xvals[frame])) ????return?line1,?text
男女人口總數(shù)
#?設(shè)置畫布 fig?=?plt.figure(figsize=(10,?5)) ax?=?plt.subplot() #?數(shù)據(jù)準(zhǔn)備 X?=?data['指標(biāo)'] male,?female?=data['男性人口(萬人)'],?data['女性人口(萬人)'] #?繪制折線圖 (line1,)?=?ax.plot(X,?male,?marker="o",? ???????????????????markevery=[-1],?markeredgecolor="white") (line2,)?=?ax.plot(X,?female,?marker="o",? ???????????????????markevery=[-1],?markeredgecolor="white") #?設(shè)置圖形注釋 text?=?ax.text(0.01,?0.75,'text',? ???????????????ha="left",?va="top",? ???????????????transform=ax.transAxes,size=20) text2?=?ax.text(X[0],male[0],?'',?ha="left",?va="top") text3?=?ax.text(X[0],female[0],?'',?ha="left",?va="top") #?設(shè)置坐標(biāo)軸刻度標(biāo)簽 ax.set_xticks(X) ax.set_yticks([]) #?設(shè)置坐標(biāo)軸線格式 ax.spines["top"].set_visible(False) ax.spines["left"].set_visible(False) ax.spines["right"].set_visible(False) #?定義更新函數(shù) def?update(frame): ????line1.set_data(X[:frame+1],?male[:frame+1]) ????line2.set_data(X[:frame+1],?female[:frame+1]) ????text.set_text("%d?人口(萬人)"?%?X[frame]) ????text2.set_position((X[frame],?male[frame])) ????text2.set_text(f'男性:?{male[frame]}') ????text3.set_position((X[frame],?female[frame])) ????text3.set_text(f'女性:?{female[frame]}') ????return?line1,line2,?text #?定義輸出 plt.tight_layout() writer?=?animation.FFMpegWriter(fps=5) #?執(zhí)行動畫 anim?=?animation.FuncAnimation(fig,?update,?interval=500,?frames=len(X)) #?存儲動畫 #?設(shè)置進(jìn)度條 bar?=?tqdm(total=len(X)) anim.save( ????"num_people2.mp4", ????writer=writer, ????dpi=300, ????progress_callback=lambda?i,?n:?bar.update(1), ) #?關(guān)閉進(jìn)度條 bar.close()
雨滴
#?設(shè)置雨滴繪圖更新函數(shù) def?rain_update(frame): ????global?R,?scatter ??#?數(shù)據(jù)獲取 ????R["color"][:,?3]?=?np.maximum(0,?R["color"][:,?3]?-?1?/?len(R)) ????R["size"]?+=?1?/?len(R) ????i?=?frame?%?len(R) ????R["position"][i]?=?np.random.uniform(0,?1,?2) ????R["size"][i]?=?0 ????R["color"][i,?3]?=?1 ????#?散點形狀設(shè)置 ????scatter.set_edgecolors(R["color"]) ????scatter.set_sizes(1000?*?R["size"].ravel()) ????scatter.set_offsets(R["position"]) ????return?(scatter,) #?繪制畫布 fig?=?plt.figure(figsize=(6,?8),?facecolor="white",?dpi=300) ax?=?fig.add_axes([0,?0,?1,?1],?frameon=False)??#?,?aspect=1) #?繪制初始化散點圖 scatter?=?ax.scatter([],?[],?s=[],? ?????????????????????linewidth=0.5,?edgecolors=[],? ?????????????????????facecolors="None",cmap='rainbow') #?設(shè)置雨滴數(shù)量 n?=?250 #?為雨滴設(shè)置參數(shù)值 R?=?np.zeros( ????n,?dtype=[("position",?float,?(2,)),? ??????????????("size",?float,?(1,)), ??????????????("color",?float,?(4,))]) R["position"]?=?np.random.uniform(0,?1,?(n,?2)) R["size"]?=?np.linspace(0,?1.5,?n).reshape(n,?1) R["color"][:,?3]?=?np.linspace(0,?1,?n) #?設(shè)置坐標(biāo)軸格式 ax.set_xlim(0,?1),?ax.set_xticks([]) ax.set_ylim(0,?1),?ax.set_yticks([]) #?保存同上
以上就是Python Matplotlib繪制動畫的代碼詳解的詳細(xì)內(nèi)容,更多關(guān)于Python Matplotlib動畫的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python接口自動化之使用token傳入到header消息頭中
這篇文章主要介紹了python接口自動化之使用token傳入到header消息頭中問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08淺談numpy中np.array()與np.asarray的區(qū)別以及.tolist
這篇文章主要介紹了淺談numpy中np.array()與np.asarray的區(qū)別以及.tolist,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06Python爬蟲基礎(chǔ)之selenium庫的用法總結(jié)
今天帶大家來學(xué)習(xí)selenium庫的使用方法及相關(guān)知識總結(jié),文中非常詳細(xì)的介紹了selenium庫,對正在學(xué)習(xí)python的小伙伴很有幫助,需要的朋友可以參考下2021-05-05使用selenium模擬動態(tài)登錄百度頁面的實現(xiàn)
本文主要介紹了使用selenium模擬動態(tài)登錄百度頁面,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Python 剪繩子的多種思路實現(xiàn)(動態(tài)規(guī)劃和貪心)
這篇文章主要介紹了Python 剪繩子的多種思路實現(xiàn)(動態(tài)規(guī)劃和貪心),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02python安裝庫的最詳細(xì)方法(以安裝pygame庫為例)
在學(xué)習(xí)了一個學(xué)期的python之后,我決定對pygame下手了,下面這篇文章主要給大家介紹了關(guān)于python安裝庫的最詳細(xì)方法,本文主要以安裝pygame庫為例,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05