當(dāng)探索具有中等數(shù)量(不多不少的意思……)維度的數(shù)據(jù)集時,一個很好的方式是基于不同的子數(shù)據(jù)集構(gòu)建不同的實例,并將它們以網(wǎng)格的方式組織在一張圖之中。這種技術(shù)有時被稱為“l(fā)attice”或“trellis”(大概是格子圖、網(wǎng)格圖),這跟“small multiples”的概念類似(多張更小的子圖)。它能幫助我們快速從復(fù)雜的數(shù)據(jù)中提取大量信息。matplotlib對于創(chuàng)建帶有多個坐標(biāo)軸(每個坐標(biāo)軸體系意味著一張子圖)的圖形有著良好的支持,seaborn基于這些來直接地將圖形的排布結(jié)構(gòu)與數(shù)據(jù)集的結(jié)構(gòu)聯(lián)結(jié)起來。
要利用這些特性,我們的數(shù)據(jù)集應(yīng)該保存在一個pandas DataFrame中,并且應(yīng)該是Hadley Whickam口中的“tidy data”格式。簡短來說,就是我們的dataframe對象中,每一行是一個觀測樣本,每一列是一個變量。
對于一些更高級的應(yīng)用來說,我們可以直接使用這篇教程中討論的一些對象來獲得最大的靈活性。一些seaborn函數(shù)(如lmplot()/catplot()/pairplot())也隱式地使用了這些對象。很多seaborn函數(shù)是坐標(biāo)軸級別的,它們僅僅針對某個特定的matplotlib Axes來繪圖,而不會修改圖形的屬性;而在這篇教程中即將討論到的這些方法是更高級別的函數(shù),在被調(diào)用時,它們會創(chuàng)建一個新的圖形,而且一般情況下對于創(chuàng)建過程更加嚴(yán)格。在某些案例中,這些函數(shù)和他們依賴的類所需要輸入的參數(shù)依賴于不同的接口屬性,比如在lmplot()中我們通過設(shè)置高度和寬高比(height和aspect)來控制每個子圖(facet)的大小,而非直接指定整個圖形的大小。這些函數(shù)在調(diào)用后都會返回這個圖形對象,而且大多數(shù)對象都提供了非常方便的方法來改變繪圖的方式,這些方法往往更加抽象和簡單。
當(dāng)我們想要基于不同的數(shù)據(jù)子集來展示某個變量的分布或者多個變量之間的關(guān)系時,F(xiàn)acetGrid類會提供很大的幫助。一個FacetGrid圖可以從三個維度來構(gòu)建:row、col和hue。前兩個與它返回的坐標(biāo)軸數(shù)組有著之間的關(guān)聯(lián);我們可以把hue變量理解為第三個維度,就像長、寬和高一樣,只不過在這里我們是用不同的顏色來體現(xiàn)它的。
在使用FacetGrid時,我們會通過一個pandas DataFrame以及控制圖形網(wǎng)格的行、列和顏色的變量名稱來初始化一個對象。這些維度變量(控制行、列和顏色的變量)應(yīng)該是分類變量或者離散變量,然后這些變量的不同水平組合起來就構(gòu)成了整個圖形的每一個子圖(facet,在這里可以理解為我們維度拆解的最小粒度)。比如說我們想要檢驗一下tips數(shù)據(jù)集中午餐和晚餐的差異。
另外,relplot()/catplot()/lmplot()內(nèi)置了FacetGrid對象,繪圖完成后他們都會返回這個對象,這樣我們就可以進行更多的調(diào)整。
傳入數(shù)據(jù)和維度變量名稱會初始化一個網(wǎng)格,其中生成了基于matplotlib的圖形和坐標(biāo)軸,但是不會在這些坐標(biāo)軸中畫任何東西(因為我們還沒告訴它們畫什么)。
在這些網(wǎng)格中畫圖的主要方式是使用FacetGrid.map()方法。我們需要告訴它使用哪個繪圖函數(shù)以及使用哪些(哪個)變量。我們用直方圖來看下兩個數(shù)據(jù)子集中小費的分布情況:
這一函數(shù)的目標(biāo)是一步到位地提供一幅完整的成品圖,它在完成繪圖后還會對每個坐標(biāo)軸添加注釋。想要生成一個戰(zhàn)士變量關(guān)系的圖,只需要傳遞更多的變量名稱進去。我們還可以提供關(guān)鍵字參數(shù),它會將他們傳遞給繪圖函數(shù):
有很多選項可以傳遞給FacetGrid的構(gòu)造函數(shù),用以控制網(wǎng)格的樣式:
需要注意的是,margin_title參數(shù)并沒有被matplotlib API提供正式支持,在某些案例中或許并不可用。比如說當(dāng)圖外邊有圖例時,它是不可用的。
圖的大小是通過每張子圖的高度和寬高比來控制的:
它默認會從DataFrame中推導(dǎo)分類的順序。如果用來控制某個方面(facet:維度/軸/角度,看哪個概念能幫助你理解它,你就用哪個名字)的變量是分類變量,那么分類變量的順序就會被使用。否則,seaborn會使用這些分類在數(shù)據(jù)集中出現(xiàn)的先后順序。當(dāng)然,我們完全可以通過*_order參數(shù)直接指定某個維度變量的順序:
我們可以指定某個seaborn調(diào)色板,也可以通過字典將hue變量中的每個分類與其對應(yīng)的matplotlib顏色傳遞給函數(shù)(這樣就可以隨心所以使用大量的matplotlib支持的色彩):
我們還可以控制hue變量的不同水平展示出來的其他樣式(方面),這些在黑白色調(diào)下(比如黑白印刷圖)對于提高圖形的可讀性尤其有用。我們需要將一個字典傳遞給hue_kws參數(shù),在這個字典中,key(字典的鍵)是繪圖函數(shù)的關(guān)鍵字參數(shù)名稱;而value(字典的值)則是一個列表,用于存儲關(guān)鍵字參數(shù)的取值,其中每個取值對應(yīng)了hue變量的一個水平。
如果某個維度變量(用于col/row/hue參數(shù)的變量,之后不再說明)具有非常多的水平(level:取值),我們可以把它們分布到不同的列,然后把它們“折疊”到不同的行中。當(dāng)我們使用這種操作時,我們不能設(shè)置row變量。
當(dāng)我們已經(jīng)使用FacetGrid.map()完成了繪圖,我們可能還想對圖形的某些方面做些調(diào)整。FacetGrid支持很多在更高層級調(diào)整圖形的方法,最常用的是FacetGrid.set(),還有一些更加具體的方法比如FacetGrid.set_axis_labels(),如圖:
想要做更多定制的話,我們可以直接操作更底層的Figure和Axes對象,它們存儲在FacetGrid.fig和FacetGrid.axes中,其中,F(xiàn)acetGrid.axes是一個二維數(shù)組。假如我們沒有指定行和列,那么我們也可以直接使用FacetGrid.ax來操作那個唯一的坐標(biāo)軸:
使用FacetGrid時,我們并非只能使用現(xiàn)成的matplotlib和seaborn繪圖函數(shù)。不過,如果想要正常工作,我們的自定義函數(shù)需要滿足一下規(guī)則:
我們來看一個符合最低條件的例子,這個繪圖函數(shù)僅接受一組來自某個分類(子數(shù)據(jù)集)的向量型數(shù)據(jù):
如果我們想要繪制一個二元圖,我們需要讓函數(shù)接受兩組數(shù)據(jù),且x軸對應(yīng)的數(shù)據(jù)在前邊,y軸對應(yīng)的數(shù)據(jù)在后邊:
由于plt.scatter可以接受關(guān)鍵字參數(shù)color和label并且能正確處理它們,所以我們可以毫不費力地增加一個hue參數(shù)(因為它的原理就是給不同的分類數(shù)據(jù)傳入不同的顏色參數(shù)):
我們還可以通過關(guān)鍵字參數(shù)控制額外的美學(xué)設(shè)計來區(qū)分hue變量的不同水平:
當(dāng)然,有時我們完全不想處理color和label。這種情況下我們需要顯式地接受他們,然后用自己的邏輯去處理他們。比如下邊這個使用plt.hexbin的例子,在與FacetGridAPI搭配的過程中。如果我們沒有手動調(diào)整顏色處理方式的話,它們的表現(xiàn)會不太好:
PairGrid也支持我們以同樣的方式快速繪制多個子圖。在PairGrid中,每行每列都被分配給一個不同的變量,所以最后生成的圖片可以展示數(shù)據(jù)集中所有的成對關(guān)系。這種風(fēng)格的圖形有時被稱作“散點圖矩陣”,因為散點圖是表現(xiàn)兩兩關(guān)系最常用的方法。不過PairGrid并不會僅僅局限于散點圖。
了解FacetGrid和PairGrid之間的區(qū)別非常重要。在FacetGrid中,每張圖表現(xiàn)的都是同樣的變量關(guān)系,只是每張圖對應(yīng)著不同的數(shù)據(jù)子集,數(shù)據(jù)子集的劃分是由我們指定的維度變量決定的(col、row和hue),這些變量相互交叉后產(chǎn)生一系列最小粒度的數(shù)據(jù)子集,每個子集就對應(yīng)了一張子圖,也就是說,不管是多少行、多少列還是多少顏色,它們都對應(yīng)著這些維度變量的取值(水平)。而在PairGrid中,每張子圖都代表了不同的兩個變量間的關(guān)系(當(dāng)然,上三角和下三角會有鏡像的關(guān)系,因為它們相當(dāng)于互換了x軸和y軸)。PairGrid可以對于我們數(shù)據(jù)集中的變量關(guān)系提供一個非??焖?、整體(不深入)的總結(jié)。
它的基本使用方法與FacetGrid非常類似。首先我們初始化一個網(wǎng)格,然后把繪圖函數(shù)傳遞給map方法,它會將我們的繪圖函數(shù)在所有的子圖中調(diào)用。與PairGrid對應(yīng)的函數(shù)是pairplot(),它失去了一些靈活性,但是讓我們的繪圖更加快捷。
我們可以在對角線上用不同的函數(shù)來展示單變量的分布情況。不過需要注意的是,軸上的刻度與分桶計數(shù)或者密度沒有關(guān)系(因為我們已經(jīng)用軸刻度去展示數(shù)據(jù)的取值了)。
在這種圖中,我們常常會對屬于不同分類的樣本標(biāo)記上不同的顏色。比如,iris數(shù)據(jù)集中有三種不同的鳶尾花,其中每個樣本都有4個特征,因此我們可以看下它們的區(qū)別在哪里。
默認情況下,數(shù)據(jù)集中所有的數(shù)值型變量都會被使用,不過我們也可以僅選用特定的列:
我們也可以分別在上三角和下三角中使用不同的函數(shù),用以強調(diào)關(guān)系的不同角度。
事實上,這種對稱的方形網(wǎng)格矩陣只是一個特例,我們可以在行和列上分別使用不同的變量。
當(dāng)然,設(shè)計(美學(xué))屬性都是可以配置的。比如,我們可以使用不同的調(diào)色板、可以給繪圖函數(shù)傳遞關(guān)鍵字參數(shù)。
PairGrid很靈活,但是想要快速觀察數(shù)據(jù)特點的話,使用pairplot()更容易。這個函數(shù)默認使用散點圖和直方圖,但是也支持一些其他類型(現(xiàn)在我們還可以在非對角位置上畫回歸圖、在對角位置上畫KDE圖),未來還會支持更多。
在pairplot()中我們也可以通過關(guān)鍵字參數(shù)調(diào)整設(shè)計風(fēng)格(美學(xué)),并且它會返回一個PairGrid對象用于更多的調(diào)整。
聯(lián)系客服