(資料科學學習手札62)詳解seaborn中的kdeplot、rugplot、distplot與jointplot

費弗裡發表於2019-07-03

一、簡介

  seaborn是Python中基於matplotlib的具有更多視覺化功能和更優美繪圖風格的繪圖模組,當我們想要探索單個或一對資料分佈上的特徵時,可以使用到seaborn中內建的若干函式對資料的分佈進行多種多樣的視覺化,本文以jupyter notebook為編輯工具,針對seaborn中的kdeplot、rugplot、distplot和jointplot,對其引數設定和具體用法進行詳細介紹。 

 

二、kdeplot

  seaborn中的kdeplot可用於對單變數和雙變數進行核密度估計並視覺化,其主要引數如下:

  data:一維陣列,單變數時作為唯一的變數

  data2:格式同data2,單變數時不輸入,雙變數作為第2個輸入變數

  shade:bool型變數,用於控制是否對核密度估計曲線下的面積進行色彩填充,True代表填充

  vertical:bool型變數,在單變數輸入時有效,用於控制是否顛倒x-y軸位置

  kernel:字元型輸入,用於控制核密度估計的方法,預設為'gau',即高斯核,特別地在2維變數的情況下僅支援高斯核方法

  legend:bool型變數,用於控制是否在影象上新增圖例

  cumulative:bool型變數,用於控制是否繪製核密度估計的累計分佈,預設為False

  shade_lowest:bool型變數,用於控制是否為核密度估計中最低的範圍著色,主要用於在同一個座標軸中比較多個不同分佈總體,預設為True

  cbar:bool型變數,用於控制是否在繪製二維核密度估計圖時在影象右側邊新增比色卡

  color:字元型變數,用於控制核密度曲線色彩,同plt.plot()中的color引數,如'r'代表紅色

  cmap:字元型變數,用於控制核密度區域的遞進色彩方案,同plt.plot()中的cmap引數,如'Blues'代表藍色系

  n_levels:int型,在而為變數時有效,用於控制核密度估計的區間個數,反映在影象上的閉環層數

  下面我們來看幾個示例來熟悉kdeplot中上述引數的實際使用方法:

  首先我們需要準備資料,本文使用seaborn中自帶的鳶尾花資料作為示例資料,因為在jupyter notebook中執行程式碼,所以加上魔術命令%matplotlib inline使得影象得以在notebook中顯示

import seaborn as sns
sns.set(color_codes=True)
import matplotlib.pyplot as plt
%matplotlib inline
#載入seaborn自帶的鳶尾花資料集,格式為資料框
iris = sns.load_dataset('iris')
#分離出setosa類的花對應的屬性值
setosa = iris.loc[iris.species == "setosa"].reset_index(drop=True)
#分離出virginica類的花對應的屬性值
virginica = iris.loc[iris.species == "virginica"].reset_index(drop=True)

  首先我們不修改其他引數只傳入資料來觀察繪製出的影象:

#繪製iris中petal_width引數的核密度估計圖
ax = sns.kdeplot(iris.petal_width)

  加上紅色填充顏色,並禁止圖例顯示:

ax = sns.kdeplot(iris.petal_width,shade=True,color='r')

  修改為核密度分佈:

ax = sns.kdeplot(iris.petal_width,
                 shade=True,
                 color='r',
                 cumulative=True)

  交換x-y軸位置:

ax = sns.kdeplot(iris.petal_width,
                 shade=True,
                 color='r',
                 vertical=True)

  下面我們來繪製雙變數聯合核密度估計圖:

#繪製setosa花的petal_width與petal_length的聯合核密度估計圖
ax = sns.kdeplot(setosa.petal_width,
                 setosa.petal_length)

  修改調色方案為藍色,並設定shade_lowest=True:

ax = sns.kdeplot(setosa.petal_width,
                 setosa.petal_length,
                 cmap='Blues',
                 shade=True,
                 shade_lowest=True)

  在上圖基礎上修改shade_lowest=False:

ax = sns.kdeplot(setosa.petal_width,
                 setosa.petal_length,
                 cmap='Blues',
                 shade=True,
                 shade_lowest=False)

可以看到這時最低密度估計曲線之外的區域沒有被調色方案所浸染。

  將核密度曲線區間個數修改為5:

ax = sns.kdeplot(setosa.petal_width,
                 setosa.petal_length,
                 cmap='Blues',
                 shade=True,
                 shade_lowest=False,
                 n_levels=5)

可以看到這時的核密度區間要粗略很多。

  在同一個子圖中繪製兩個不同一維總體的核密度估計圖,這裡為了把它們區分開分別定義了label引數以顯示在圖例中:

ax1 = sns.kdeplot(setosa.petal_width,label='setosa.petal_width')
ax2 = sns.kdeplot(virginica.petal_width,label='virginica.petal_width')

  在同一個子圖中繪製兩個不同二維總體的核密度估計圖:

ax1 = sns.kdeplot(setosa.sepal_width,setosa.sepal_length,
                  cmap='Blues',
                  shade=True,
                  shade_lowest=False)
ax2 = sns.kdeplot(virginica.sepal_width,virginica.sepal_length,
                  cmap='Greens',
                  shade=True,
                  shade_lowest=False)

 

三、rugplot

  rugplot的功能非常樸素,用於繪製出一維陣列中資料點實際的分佈位置情況,即不新增任何數學意義上的擬合,單純的將記錄值在座標軸上表現出來,相對於kdeplot,其可以展示原始的資料離散分佈情況,其主要引數如下:

  a:一維陣列,傳入觀測值向量

  height:設定每個觀測點對應的小短條的高度,預設為0.05

  axis:字元型變數,觀測值對應小短條所在的軸,預設為'x',即x軸

  

  使用預設引數進行繪製:

ax = sns.rugplot(iris.petal_length)

  調換所處的座標軸:

ax = sns.rugplot(iris.petal_length,axis='y')

  修改小短條高度和顏色:

ax = sns.rugplot(iris.petal_length,
                 color='r',
                 height=0.2)

 

三、distplot

  seaborn中的distplot主要功能是繪製單變數的直方圖,且還可以在直方圖的基礎上施加kdeplot和rugplot的部分內容,是一個功能非常強大且實用的函式,其主要引數如下:

  a:一維陣列形式,傳入待分析的單個變數

  bins:int型變數,用於確定直方圖中顯示直方的數量,預設為None,這時bins的具體個數由Freedman-Diaconis準則來確定

  hist:bool型變數,控制是否繪製直方圖,預設為True

  kde:bool型變數,控制是否繪製核密度估計曲線,預設為True

  rug:bool型變數,控制是否繪製對應rugplot的部分,預設為False

  fit:傳入scipy.stats中的分佈型別,用於在觀察變數上抽取相關統計特徵來強行擬合指定的分佈,下文的例子中會有具體說明,預設為None,即不進行擬合

  hist_kws,kde_kws,rug_kws:這幾個變數都接受字典形式的輸入,鍵值對分別對應各自原生函式中的引數名稱與引數值,在下文中會有示例

  color:用於控制除了fit部分擬合出的曲線之外的所有物件的色彩

  vertical:bool型,控制是否顛倒x-y軸,預設為False,即不顛倒

  norm_hist:bool型變數,用於控制直方圖高度代表的意義,為True直方圖高度表示對應的密度,為False時代表的是對應的直方區間內記錄值個數,預設為False

  label:控制影象中的圖例標籤顯示內容

  

  使用預設引數進行繪製:

ax = sns.distplot(iris.petal_length)

  修改所有物件的顏色,繪製rugplot部分,並修改bins為20:

ax = sns.distplot(iris.petal_length,color='r',
                 rug=True,
                 bins=20)

  在上圖的基礎上強行擬合卡方分佈並利用引數字典設定fit曲線為綠色:

from scipy.stats import chi2                
ax = sns.distplot(iris.petal_length,color='r',
                 rug=True,
                 bins=20,
                 fit=chi2,
                 fit_kws={'color':'g'})

  修改norm_hist引數為False使得縱軸顯示的不再是密度而是頻數(注意這裡必須關閉kde和fit繪圖的部分,否則縱軸依然顯示密度),利用hist_kws傳入字典調整直方圖部分色彩和透明度,利用rug_kws傳入字典調整rugplot部分小短條色彩:

ax = sns.distplot(iris.petal_length,color='r',
                 rug=True,
                 kde=False,
                 bins=20,
                 fit=None,
                 hist_kws={'alpha':0.6,'color':'orange'},
                 rug_kws={'color':'g'},
                 norm_hist=False)

 

四、jointplot

  之所以按照kdeplot-rugplot-distplot的順序來介紹是因為distplot中涉及到kdeplot與rugplot中的相關內容,而本文最後要介紹的函式jointplot中聚合了前面所涉及到的眾多內容,用於對成對變數的相關情況、聯合分佈以及各自的分佈在一張圖上集中呈現,其主要引數如下:

  x,y:代表待分析的成對變數,有兩種模式,第一種模式:在引數data傳入資料框時,x、y均傳入字串,指代資料框中的變數名;第二種模式:在引數data為None時,x、y直接傳入兩個一維陣列,不依賴資料框

  data:與上一段中的說明相對應,代表資料框,預設為None

  kind:字元型變數,用於控制展示成對變數相關情況的主圖中的樣式

  color:控制影象中物件的色彩

  height:控制影象為正方形時的邊長

  ratio:int型,調節聯合圖與邊緣圖的相對比例,越大則邊緣圖越矮,預設為5

  space:int型,用於控制聯合圖與邊緣圖的空白大小

  xlim,ylim:設定x軸與y軸顯示範圍

  joint_kws,marginal_kws,annot_kws:傳入引數字典來分別精細化控制每個元件

  

  在預設引數設定下繪製成對變數聯合圖:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa)

值得一提的是,jointplot還貼心的在影象上說明了成對變數之間的皮爾遜簡單相關係數以及相關性檢驗的p值結果。

  將kind引數設定為'reg',為聯合圖新增線性迴歸擬合直線與核密度估計結果:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                  kind='reg')

  修改kind為'hex'來為聯合圖生成六邊形核密度估計:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                  kind='hex')

  修改kind為'kde'來將直方圖和散點圖轉換為核密度估計圖,並將邊際軸的留白大小設定為0:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                   kind='kde',
                   space=0,
                   color='g')

  jointplot還支援圖層疊加,如下面的例子,我們首先繪製出的聯合圖中kind限制為擬合線性迴歸直線,在此基礎上利用.plot_joint方法疊加核密度估計圖層:

ax = (sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                   color='g',
                   kind='reg')).plot_joint(sns.kdeplot, zorder=0, n_levels=10)

根據你的具體需要還可以疊加出更加豐富的影象。

  調大ratio引數使得邊緣圖更加小巧:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                   kind='kde',
                   space=0,
                   color='g',
                   ratio=15)

  利用邊緣圖形引數字典為邊緣圖形新增rugplot的內容,並修改直方個數為15:

ax = sns.jointplot(x='sepal_length',y='sepal_width',data=setosa,
                   marginal_kws=dict(bins=15, rug=True),
                   linewidth=1,space=0)

  實際上,如果你足夠了解matplotlib與seaborn,可以通過各種組合得到資訊量更豐富特別的影象!

 

 

  以上就是本文的全部內容,如有筆誤望指出!

 

相關文章