利用?Python?讓圖表動起來
用Matplotlib
和Seaborn
這類Python
庫可以畫出很好看的圖,但是這些圖只是靜態(tài)的,難以動態(tài)且美觀地呈現(xiàn)數(shù)值變化。要是在你下次的演示、視頻、社交媒體Po文里能用短視頻呈現(xiàn)數(shù)據(jù)變化,是不是很贊呢?更棒的是,你還是可以在你的圖表上用Matplotlib
、Seaborn
或者其他庫!
本文將使用美國國家藥物濫用研究所和疾病預(yù)防控制中心公布的藥物數(shù)據(jù),可在此處下載:https://http://www.drugabuse.gov/sites/default/files/overdosedata1999-2015.xls
我們會用到的數(shù)據(jù)是這樣的:
我們將用Matplotlib
和Seaborn
繪圖,用Numpy
和Pandas
處理數(shù)據(jù)。Matplotlib
也提供了一些我們做動畫可以的函數(shù),所以讓我們首先導(dǎo)入所有依賴項。
import numpy as np import pandas as pd import seaborn as sns import matplotlib import matplotlib.pyplot as plt import matplotlib.animation as animation
然后用Pandas
載入數(shù)據(jù)并轉(zhuǎn)成DataFrame
類型的數(shù)據(jù)結(jié)構(gòu)。因為我們要針對不同類藥物的濫用畫圖,寫個函數(shù)來載入感興趣的特定行的數(shù)據(jù)能避免重復(fù)代碼。(小編注:原文提供的代碼在讀取excel
文件的時候使用了已廢棄的sheetname
參數(shù),本文中已修正為sheet_name)
overdoses = pd.read_excel('overdose_data_1999-2015.xls',sheet_name='Online',skiprows =6) def get_data(table,rownum,title): data = pd.DataFrame(table.loc[rownum][2:]).astype(float) data.columns = {title} return data
現(xiàn)在讓我們來做動畫吧!
首先,如果你和我一樣使用的是jupyter notebook
,請在代碼首行加入 %matplotlib notebook
,如此便可在notebook
直接看到生成的動畫而非保存后才可見。
我現(xiàn)在使用 get_data
函數(shù)從表中檢索過量的數(shù)據(jù)并放在有兩列的Pandas DataFrame
中,一列是年,一列是過量死亡的人數(shù)。
%matplotlib notebook title = 'Heroin Overdoses' d = get_data(overdoses,18,title) x = np.array(d.index) y = np.array(d['Heroin Overdoses']) overdose = pd.DataFrame(y,x) #XN,YN = augment(x,y,10) #augmented = pd.DataFrame(YN,XN) overdose.columns = {title}
接下來我們初始化一個ffmpeg Writer
并以20幀每秒、1800比特率進行錄屏。你也可以根據(jù)喜好自行設(shè)置這些值。
Writer = animation.writers['ffmpeg'] writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)
(小編注:如果出現(xiàn) RuntimeError:RequestedMovieWriter(ffmpeg)notavailable
的報錯,請自行安裝ffmpeg
,裝了brew
的Mac
可以直接: brew install ffmpeg
)
現(xiàn)在我們創(chuàng)建一個有幾個標簽的圖形。確保設(shè)置x和y軸的限制,以免動畫隨當(dāng)前顯示的數(shù)據(jù)范圍亂跳轉(zhuǎn)。
fig = plt.figure(figsize=(10,6)) plt.xlim(1999, 2016) plt.ylim(np.min(overdose)[0], np.max(overdose)[0]) plt.xlabel('Year',fontsize=20) plt.ylabel(title,fontsize=20) plt.title('Heroin Overdoses per Year',fontsize=20)
動畫的核心是動畫函數(shù),你可以在其中定義視頻的每一幀發(fā)生什么。這里的 i表示動畫中幀的索引。使用這個索引可以選擇應(yīng)在此幀中可見的數(shù)據(jù)范圍。然后我使用seaborn
線圖來繪制所選的數(shù)據(jù)。最后兩行代碼只是為了讓圖表更美觀。
def animate(i): data = overdose.iloc[:int(i+1)] #選擇數(shù)據(jù)范圍 p = sns.lineplot(x=data.index, y=data[title], data=data, color="r") p.tick_params(labelsize=17) plt.setp(p.lines,linewidth=7)
我們用調(diào)用了 animate
函數(shù)并定義了幀數(shù)的 matplotlib.animation.FuncAnimation
來開始動畫, frames
實際上定義了調(diào)用 animate
的頻率。
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=17, repeat=True)
你可以用 ani.save()
把動畫保存為mp4
,如果你想直接看一看動畫效果可以用plt.show()
。
ani.save('HeroinOverdosesJumpy.mp4', writer=writer)
現(xiàn)在我們的圖表動起來啦:
動畫能夠正常運行但是感覺有點跳躍,所以我們需要在已有數(shù)據(jù)點之間增加更多的數(shù)據(jù)點來使動畫的過渡平滑。于是我們使用另一個函數(shù) augment
。
def augment(xold,yold,numsteps): xnew = [] ynew = [] for i in range(len(xold)-1): difX = xold[i+1]-xold[i] stepsX = difX/numsteps difY = yold[i+1]-yold[i] stepsY = difY/numsteps for s in range(numsteps): xnew = np.append(xnew,xold[i]+s*stepsX) ynew = np.append(ynew,yold[i]+s*stepsY) return xnew,ynew
現(xiàn)在我們只需要對我們的數(shù)據(jù)應(yīng)用這個函數(shù)、增加 matplotlib.animation.FuncAnimation
函數(shù)的幀數(shù)。在這里我用參數(shù) numsteps=10
調(diào)用 augment
函數(shù),也就是增加數(shù)據(jù)點至160個,并且設(shè)置 frames=160
。這樣以來,圖表顯得更為平滑,但還是在數(shù)值變動處有些突兀。
為了讓我們的動畫更平滑美觀,我們可以增加一個平滑函數(shù)(具體請見:https://www.swharden.com/wp/2008-11-17-linear-data-smoothing-in-python/ )。
def smoothListGaussian(listin,strippedXs=False,degree=5): window=degree*2-1 weight=np.array([1.0]*window) weightGauss=[] for i in range(window): i=i-degree+1 frac=i/float(window) gauss=1/(np.exp((4*(frac))**2)) weightGauss.append(gauss) weight=np.array(weightGauss)*weight smoothed=[0.0]*(len(listin)-window) for i in range(len(smoothed)): smoothed[i]=sum(np.array(listin[i:i+window])*weight)/sum(weight) return smoothed
另外我們也可以加上一點顏色和樣式參數(shù),讓圖表更個性化。
sns.set(rc={'axes.facecolor':'lightgrey', 'figure.facecolor':'lightgrey','figure.edgecolor':'black','axes.grid':False})
當(dāng)當(dāng)當(dāng)!如此我們便得到了文章開頭的動畫圖表。
這篇文章僅僅只是matplotlib
動畫功能的一個例子,你大可以用它來實現(xiàn)任何一種圖表的動畫效果。簡單調(diào)整 animate()
函數(shù)內(nèi)的參數(shù)和圖表類型,就能得到無窮無盡的可能性。
到此這篇關(guān)于利用 Python 讓圖表動起來的文章就介紹到這了,更多相關(guān)Python 讓圖表動起來內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python利用shutil模塊實現(xiàn)文件的裁剪與壓縮
shutil可以簡單地理解為sh+util ,shell工具的意思。shutil模塊是對os模塊的補充,主要針對文件的拷貝、刪除、移動、壓縮和解壓操作。本文將利用這一模塊實現(xiàn)文件的裁剪、壓縮與解壓縮,需要的可以參考一下2022-05-05TensorFlow卷積神經(jīng)網(wǎng)絡(luò)MNIST數(shù)據(jù)集實現(xiàn)示例
這篇文章主要介紹了TensorFlow卷積神經(jīng)網(wǎng)絡(luò)MNIST數(shù)據(jù)集的實現(xiàn)示例的過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2021-11-11