全文共3576字,預計學習時長10分鐘或更長
Seaborn和Matplotlib是Python最強大的兩個可視化庫。Seaborn其默認主題讓人驚訝,而Matplotlib可以通過其多個分類為用戶打造專屬功能。
Python提供了各種用於繪製數據的包。本教程將使用以下兩種包來演示Python的繪圖功能:
· Matplotlib
· Seaborn
Matplotlib
importmatplotlib.pyplot as plt%matplotlib inlineimport numpy as np
在上面的代碼塊中,將Pyplot模塊調整為plt格式並導入Matplotliib庫。這樣做可以簡化執行命令的過程,具體內容會在本篇教程中看到。PyPlot包含創建和編輯繪圖所需的一系列命令。操作時同時運行%matplotlibinline,那麼繪圖下方就能自動顯示代碼塊,否則用戶每次繪圖時都需要輸入plt.show()來創建新圖。此功能是Jupyter Notebook / IPython獨有的。Matplotlib擁有定製的代碼塊結構,這使得它比其他繪圖庫更先進。接下來看看如何使用matploblib生成散點圖。
提示:當使用matplotlib時,文本輸出無法帶來視覺上的吸引力。為了解決這個問題,我們在執行代碼塊生成圖片時會在每一行代碼末端添加分號「;」。
我們使用的資料庫是UCI機器學習庫中的共享單車數據集。
Matplotlib: 散點圖
散點圖是各種示意圖中影響力最廣、信息量最大、功能最多的一類圖。它可以直接向用戶傳遞信息,無需太多額外工作(如下圖所示)。
· plt.scatter()將輸入的散點圖上的數據作為初始參數,其中temp指x軸,cnt指y軸。
· c指的是不同數據點的顏色。輸入一個字符串「季節」,它也表示數據幀中的一列,不同顏色對應不同季節。該方法用可視化方法對數據分組,十分簡單便捷。
plt.scatter('temp','cnt', data=day, c='season')plt.xlabel('NormalizedTemperature', fontsize='large')plt.ylabel('Countof Total Bike Rentals', fontsize='large');
圖上信息顯示:
· 某些時間點的自行車租賃量超過8000輛。
· 標準溫度超過0.8。
· 自行車租賃量與溫度或季節無關。
· 自行車租賃量與標準溫度之間含有正線性關係。
這個圖的確含有大量信息,然而圖表並不能產生圖例,因此我們很難對各組季節數據進行破譯。這是因為用散點圖繪圖時,Matplotlib無法根據繪圖製作圖例。下一節中,我們將會看到該圖如何隱藏信息,甚至誤導讀者。
看看經過徹底編輯後的繪圖。該圖旨在根據不同組別繪製圖例,並進行破譯。
plt.rcParams['figure.figsize']= [15, 10]fontdict={'fontsize':18,'weight' : 'bold', 'horizontalalignment': 'center'}fontdictx={'fontsize':18, 'weight' : 'bold', 'horizontalalignment': 'center'}fontdicty={'fontsize':16, 'weight' : 'bold', 'verticalalignment': 'baseline', 'horizontalalignment': 'center'}spring =plt.scatter('temp', 'cnt', data=day[day['season']==1], marker='o',color='green')summer =plt.scatter('temp', 'cnt', data=day[day['season']==2], marker='o', color='orange')autumn =plt.scatter('temp', 'cnt', data=day[day['season']==3], marker='o',color='brown')winter =plt.scatter('temp', 'cnt', data=day[day['season']==4], marker='o',color='blue')plt.legend(handles=(spring,summer,autumn,winter), labels=('Spring', 'Summer','Fall/Autumn', 'Winter'), title="Season",title_fontsize=16, scatterpoints=1, bbox_to_anchor=(1, 0.7), loc=2,borderaxespad=1., ncol=1, fontsize=14)plt.title('BikeRentals at Different Temperatures\nBy Season', fontdict=fontdict,color="black")plt.xlabel("Normalizedtemperature", fontdict=fontdictx)plt.ylabel("Countof Total Rental Bikes", fontdict=fontdicty);
· plt.rcParams['figure.figsize']= [15, 10]限定了整張圖的大小,這個代碼對應的是一個長15釐米*寬10釐米的圖。
· Fontdict是一個包含許多參數的字典,可以用於標記不同的軸,其中標題為fontdict,x軸為fontdictx,y軸為fontdicty。
· 如今有四個plt.scatter()函數,對應四個不同的季節,這一點在數據參數中再次出現,而這些數據參數已被子集化以對應不同單一季節。「o」表示不同的標記和顏色參數,這可以直觀地顯示數據點的位置以及其顏色。
· 在plt.legend()中輸入參數形成圖例。前兩個參數是句柄:圖例和標籤會展示真正的散點圖;而於各個圖對應的名字也會在圖例中出現。圖上大小不一的標記代表散點,它們最終組合為一個散點圖。bbox_to_anchor=(1, 0.7), loc=2, borderaxespad=1。這三個參數串聯使用,來對照圖例位置。點擊這句話開頭的連結,可以發現這些參數的本質。
現在可以通過區分不同季節來發現更多隱藏信息。但即使已經添加了額外的圖層,散點圖依然可以隱藏信息並帶來誤解。
該散點圖:
· 數據中有重複部分。
· 分布混亂。
· 未顯示自行車租賃在不同季節之間的明顯差別。
· 隱藏信息,如:春夏氣溫上升時自行車出租量會增加。
· 表示自行車租賃量與氣溫呈正比關係。
· 並未清楚顯示最低溫出現在哪一季節。
子圖
創建子圖可能是業界最具吸引力也是最專業的圖表技術之一。當單一的圖信息過多時,人們難以評估,子圖就變得十分重要。
分面就是在同一個軸上繪製多個不同的圖。分面是數據可視化中功能最多的技術之一。分面可以從多個角度展示信息,也可以揭露隱藏內容。
· 如前所述,plt.figure()將用於創建新的繪圖畫布。最終會保存為圖畫格式。
· 重複運行fig.add_subplot()代碼4次,分別對應四個季節的子圖。其參數則對應nrows,ncols和index。比方說axl對應圖表上第一個繪圖(索引在左上角從1開始,向右遞增)。
· 餘下的函數調用可以自我解釋或被覆蓋。
fig = plt.figure()plt.rcParams['figure.figsize']= [15,10]plt.rcParams["font.weight"]= "bold"fontdict={'fontsize':25,'weight' : 'bold'}fontdicty={'fontsize':18, 'weight' : 'bold', 'verticalalignment': 'baseline', 'horizontalalignment': 'center'}fontdictx={'fontsize':18, 'weight' : 'bold', 'horizontalalignment': 'center'}plt.subplots_adjust(wspace=0.2,hspace=0.2)fig.suptitle('BikeRentals at Different Temperatures\nBy Season',fontsize=25,fontweight="bold", color="black", position=(0.5,1.01))ax1 =fig.add_subplot(221)ax1.scatter('temp','cnt', data=day[day['season']==1], c="green")ax1.set_title('Spring',fontdict=fontdict, color="green")ax1.set_ylabel("Countof Total Rental Bikes", fontdict=fontdicty, position=(0,-0.1))ax2 =fig.add_subplot(222)ax2.scatter('temp','cnt', data=day[day['season']==2], c="orange")ax2.set_title('Summer',fontdict=fontdict, color="orange")ax3 =fig.add_subplot(223)ax3.scatter('temp','cnt', data=day[day['season']==3], c="brown")ax3.set_title('Fallor Autumn', fontdict=fontdict, color="brown")ax4 =fig.add_subplot(224)ax4.scatter('temp','cnt', data=day[day['season']==4], c="blue")ax4.set_title("Winter",fontdict=fontdict, color="blue")ax4.set_xlabel("Normalizedtemperature", fontdict=fontdictx, position=(-0.1,0));
現在分別分析各組,效果也會更加顯著。首先要注意到在不同季節裡,自行車租賃量與氣溫的關係存在差異:
· 它們在春天呈現正線性關係。
· 它們在冬天和夏天呈二次非線性關係。
· 在秋天它們的正線性關係十分不明顯。
但是,這些圖依然有可能誤導讀者,原因也並不明顯。四張圖中,所有的軸都不一樣。如果人們沒有留意到這一點,那麼他們很有可能會誤解這些圖。請參閱下文,了解如何解決該問題。
fig = plt.figure()plt.rcParams['figure.figsize']= [12,12]plt.rcParams["font.weight"]= "bold"plt.subplots_adjust(hspace=0.60)fontdicty={'fontsize':20,'weight' : 'bold', 'verticalalignment': 'baseline', 'horizontalalignment': 'center'}fontdictx={'fontsize':20, 'weight' : 'bold', 'horizontalalignment': 'center'}fig.suptitle('BikeRentals at Different Temperatures\nBy Season',fontsize=25,fontweight="bold", color="black", position=(0.5,1.0))#ax2 is definedfirst because the other plots are sharing its x-axisax2 =fig.add_subplot(412, sharex=ax2)ax2.scatter('temp','cnt', data=day.loc[day['season']==2], c="orange")ax2.set_title('Summer',fontdict=fontdict, color="orange")ax2.set_ylabel("Countof Total Rental Bikes", fontdict=fontdicty, position=(-0.3,-0.2))ax1 =fig.add_subplot(411, sharex=ax2)ax1.scatter('temp','cnt', data=day.loc[day['season']==1], c="green")ax1.set_title('Spring',fontdict=fontdict, color="green")ax3 =fig.add_subplot(413, sharex=ax2)ax3.scatter('temp','cnt', data=day.loc[day['season']==3], c="brown")ax3.set_title('Fallor Autumn', fontdict=fontdict, color="brown")ax4 =fig.add_subplot(414, sharex=ax2)ax4.scatter('temp','cnt', data=day.loc[day['season']==4], c="blue")ax4.set_title('Winter',fontdict=fontdict, color="blue")ax4.set_xlabel("Normalizedtemperature", fontdict=fontdictx);
如今繪圖網格重新調整,所有圖的x軸都與夏天圖的x軸一致(選擇夏天的x軸為標準是因為它的溫度範圍更廣)。現在可以從數據中找到一些更有趣的發現:
· 最低溫度出現在春天。
· 最高溫度出現在秋天。
· 在夏天和秋天,自行車租賃量和溫度似乎呈二次關係。
· 不考慮季節因素時,溫度越低,自行車租賃量越少。
· 春天的自行車租賃量和溫度呈明顯的正線性關係。
· 秋天的自行車租賃量和溫度呈輕度的負線性關係。
fig = plt.figure()plt.rcParams['figure.figsize']= [10,10]plt.rcParams["font.weight"]= "bold"plt.subplots_adjust(wspace=0.5)fontdicty1={'fontsize':18,'weight' : 'bold'}fontdictx1={'fontsize':18, 'weight' : 'bold', 'horizontalalignment': 'center'}fig.suptitle('BikeRentals at Different Temperatures\nBy Season',fontsize=25,fontweight="bold", color="black", position=(0.5,1.0))ax3 =fig.add_subplot(143, sharey=ax3)ax3.scatter('temp','cnt', data=day.loc[day['season']==3], c="brown")ax3.set_title('Fallor Autumn', fontdict=fontdict,color="brown")ax1 =fig.add_subplot(141, sharey=ax3)ax1.scatter('temp','cnt', data=day.loc[day['season']==1], c="green")ax1.set_title('Spring',fontdict=fontdict, color="green")ax1.set_ylabel("Countof Total Rental Bikes", fontdict=fontdicty1, position=(0.5,0.5))ax2 =fig.add_subplot(142, sharey=ax3)ax2.scatter('temp','cnt', data=day.loc[day['season']==2], c="orange")ax2.set_title('Summer',fontdict=fontdict, color="orange")ax4 =fig.add_subplot(144, sharey=ax3)ax4.scatter('temp','cnt', data=day.loc[day['season']==4], c="blue")ax4.set_title('Winter',fontdict=fontdict, color="blue")ax4.set_xlabel("Normalizedtemperature", fontdict=fontdictx, position=(-1.5,0));
將所有繪圖並列放置又有新的發現:
· 所有季節都有超過8000輛自行車出租的時間點。
· 大規模的自行車出租主要出現在春秋兩季。
· 冬夏兩季中自行車租賃量變動較大。
但注意,不要從以上方面來解釋變量之間的關係。儘管春夏兩季中自行車租賃量與氣溫似乎存在負線性關係,但這一解釋實際是錯誤的。從前文的分析中我們發現事實並非如此。
Seaborn
seaborn包是基於Matplotlib庫開發的。它用於創建更具吸引力、信息量更大的統計圖形。雖然seaborn與Matplotlib不一樣,但它創建的圖像一樣具有吸引力。
儘管matplotlib表現不俗,但我們總希望做得更好。運行下面的代碼塊以導入seaborn庫,並創建先前的散點圖,來看看會出現什麼。
首先輸入代碼import seaborn assns,將seaborn庫導入。下一行sns.set()將seaborn的默認主題和調色板加載到會話中。運行下面的代碼並觀察圖表中哪些區域或文字發生更改。
import seaborn assnssns.set()
將seaborn加載到會話中後,當使用Matplotlib生成圖像時,這個庫會添加seaborn的默認自定義項,如圖所示。而最令用戶感到困擾的便是它們的標題有可能會重複——Matplotlib的命名規則讓人困惑,這一點也讓人覺得厭煩。儘管如此,這些視覺效果依然很有吸引力,數據科學家的工作已引入這一技術。
為了使標題更加與時俱進,提高其用戶友好度,需要使用如下代碼。但注意,以下代碼僅適用於散點圖中含有副標題的情況。有的時候副標題也十分重要,因此仍需更好地掌握這種結構。
fig = plt.figure()fig.suptitle('Seabornwith Python', fontsize='x-large', fontweight='bold')fig.subplots_adjust(top=0.87)#This is used forthe main title. 'figure()' is a class that provides all the plotting elementsof a diagram.#This must be usedfirst or else the title will not show.fig.subplots_adjust(top=0.85) solves ouroverlapping title problem.ax =fig.add_subplot(111)fontdict={'fontsize':14,'fontweight' : 'book', 'verticalalignment': 'baseline', 'horizontalalignment': 'center'}ax.set_title('PlottingTutorial', fontdict=fontdict)#This specifieswhich plot to add the customizations. fig.add_sublpot(111) corresponds to topleft plot no.1#(there is only oneplot).plt.plot(x, y,'go-', linewidth=1) #linewidth=1 to make it narrowerplt.xlabel('x-axis',fontsize=14)plt.ylabel('yaxis',fontsize=14);
深入挖掘seaborn的功能後,我們可以用更少的代碼行與類似的語法對自行車租賃量數據集再次創建可視化圖。Seaborn仍然使用Matplotlib語法來生成圖像,儘管新圖與舊圖之間的語法差異很小,但依然十分明顯。
為了簡化視覺效果,我們將對自行車租賃數據集的「季節」列重新命名,並重新標記。
day.rename(columns={'season':'Season'},inplace=True)day['Season']=day.Season.map({1:'Spring',2:'Summer', 3:'Fall/Autumn', 4:'Winter'})
如今我們已根據喜好重新編輯了「季節」一欄,接下來將用seaborn對先前的繪圖進行可視化。
第一個明顯的區別在於——當默認樣式加入到會話後,seaborn顯示的默認主題不一致。上面顯示的默認主題是在調用sns.set()時在後臺應用sns.set_style('whitegrid')的結果。我們也可以根據喜好用已有主題改變原來的狀態,如下圖所示。
· sns.set_style()標記的是「white」、「dark」、「whitegrid」以及「darkgrid」中的一個。這一代碼控制著整個繪圖區域,比如顏色,網格以及標記的狀態。
· sns.set_context()表示的是「paper」、「notebook」、「talk」和「poster」的內容。這將根據讀取方式控制繪圖的布局。例如,如果內容出現在「poster」上,我們將看到放大的圖像和文字。如果內容出現在 「talk」中,其字體將會加粗。
plt.figure(figsize=(7,6))fontdict={'fontsize':18,'weight' : 'bold', 'horizontalalignment': 'center'}sns.set_context('talk',font_scale=0.9)sns.set_style('ticks')sns.scatterplot(x='temp',y='cnt', hue='Season', data=day, style='Season', palette=['green','orange','brown','blue'], legend='full')plt.legend(scatterpoints=1, bbox_to_anchor=(1, 0.7), loc=2,borderaxespad=1., ncol=1, fontsize=14)plt.xlabel('NormalizedTemperature', fontsize=16, fontweight='bold')plt.ylabel('Countof Total Bike Rentals', fontsize=16, fontweight='bold')plt.title('BikeRentals at Different Temperatures\nBy Season', fontdict=fontdict, color="black", position=(0.5,1));
現在來看一個相同的散點圖,但其輸入代碼為sns.set_context('paper',font_scale=2)和sns.set_style('white')
plt.figure(figsize=(7,6))fontdict={'fontsize':18,'weight' : 'bold', 'horizontalalignment': 'center'}sns.set_context('paper',font_scale=2) #this makes the font and scatterpoints much smaller, hence theneed for size adjustemntssns.set_style('white')sns.scatterplot(x='temp',y='cnt', hue='Season', data=day, style='Season', palette=['green','orange','brown','blue'],legend='full', size='Season', sizes=[100,100,100,100])plt.legend(scatterpoints=1, bbox_to_anchor=(1, 0.7), loc=2,borderaxespad=1., ncol=1, fontsize=14)plt.xlabel('NormalizedTemperature', fontsize=16, fontweight='bold')plt.ylabel('Countof Total Bike Rentals', fontsize=16, fontweight='bold')plt.title('BikeRentals at Different Temperatures\nBy Season', fontdict=fontdict,color="black", position=(0.5,1));
現在終於用Seaborn重新創建了之前用Matplotlib生成的散點圖。更改後的圖使用的代碼行數更少,解析度也更高。接下來繼續完成繪圖:
sns.set(rc={'figure.figsize':(20,20)})sns.set_context('talk',font_scale=2)sns.set_style('ticks')g =sns.relplot(x='temp', y='cnt', hue='Season', data=day,palette=['green','orange','brown','blue'],col='Season', col_wrap=4,legend=False height=6, aspect=0.5,style='Season', sizes=(800,1000))g.fig.suptitle('BikeRentals at Different Temperatures\nBy Season' ,position=(0.5,1.05),fontweight='bold', size=18)g.set_xlabels("NormalizedTemperature",fontweight='bold', size=15)g.set_ylabels("Countof Total Bike Rentals",fontweight='bold', size=20);
改變圖表形狀需要改變外觀參數。通過增大外觀的數值,圖表形狀會更呈方形。圖像高度也會隨著數值更改發生變化,因此這裡需要同時對兩個參數進行試驗。
更改行數和列數需使用col_wrap參數執行此操作。行數和列數會隨著col參數而變化。這種參數可以檢測類比數目,同時可以相應地分配。
sns.set(rc={'figure.figsize':(20,20)})sns.set_context('talk',font_scale=2)sns.set_style('ticks')g =sns.relplot(x='temp', y='cnt', hue='Season',data=day,palette=['green','orange','brown','blue'],col='Season', col_wrap=2,legend=False height=4, aspect=1.6,style='Season', sizes=(800,1000))g.fig.suptitle('BikeRentals at Different Temperatures\nBy Season' ,position=(0.5,1.05),fontweight='bold', size=18)g.set_xlabels("NormalizedTemperature",fontweight='bold', size=15)g.set_ylabels("Countof\nTotal Bike Rentals",fontweight='bold', size=20);
留言 點讚 關注
我們一起分享AI學習與發展的乾貨
歡迎關注全平臺AI垂類自媒體 「讀芯術」