本文是基于StackAbuse的一篇講解Seaborn的文章 上編寫。 附示例及實作代碼,可直接前往文末 一鍵克隆代碼 進行實踐研究。
在前一篇文章 Pandas資料可視化工具——Seaborn用法整理(上),我們了解了如何使用這些Seaborn代碼繪制分布圖和分類圖。在本文中,我們将繼續讨論Seaborn提供的一些其他以繪制不同類型統計圖的功能,我們将從矩陣圖開始讨論。
矩陣圖
矩陣圖是一種以行和列的形式顯示資料的圖。Heat maps是矩陣圖的一個典型例子。
Heat Maps
Heat Maps通常用于以矩陣形式繪制數值列之間的相關性。這裡需要提到的是,要繪制矩陣圖,需要有關于行和列的有價值的資訊。延續上一篇文章的主題,我們将使用财報資料10-18年的資料,看看行和列标題是否都是有意義的資訊。執行以下代碼:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = DataSource('financial_statement_CN_STOCK_A').read(start_date='2010-04-01',end_date='2018-04-02')
df.head()
在輸出中,您将看到如下結果:

從輸出中可以看到,列标頭包含有用的資訊,如股票代碼、日期、固定資産、營業利潤等。而行标頭隻包含索引0、1、2等。一種方法是調用資料集上的corr()方法。函數的作用是:傳回資料集中所有數字列之間的相關性。執行以下代碼:
df_0 = df[['date','instrument','fs_operating_profit','fs_current_assets','fs_net_profit_ttm','fs_roe','fs_gross_profit_margin','fs_free_cash_flow']]
df_0.corr()
(這裡為了使結果圖簡潔,隻選擇了六個統計量。)
在輸出中,您将看到各列之間的相關系數,如下所示:
現在,要建立具有這些相關值的Heat Maps,需要調用heatmap()函數并将相關系數的DataFrame傳遞給它。請看下面的代碼:
sns.heatmap(df_0.corr())
在輸出中,您将看到如下結果:
從輸出中可以看出,heatmap的基本功能是為行和列值的每個組合繪制一個框。圖像的顔色取決于漸變。例如,在上面的圖像中,如果兩個特征之間有很高的相關性,對應的單元格或者方框是白偏向于色的,另一方面,如果沒有相關性,對應的單元格是黑色的。
通過為傳遞參數annot為True,相關系數也可以繪制在heatmap上。執行下面的代碼,看看這是否有效:
sns.heatmap(df_0.corr(), annot=True)
您還可以通過給cmap傳遞參數來更改heatmap的顔色。現在,看看下面的代碼:
sns.heatmap(df_0.corr(), cmap='winter')
結果如下:
除了僅使用所有列之間的相關性之外,還可以使用pivot_table函數指定索引、列以及希望看到的與索引和列對應的值。為了展示pivot_table函數的運作情況,我們可以觀察單個股票的情況。這裡我們
執行以下代碼導入資料集并檢視資料集的前5行:
df_1 = df.ix[df['instrument']=='600760.SHA']#選出某一隻股票單獨作圖(否則圖像無意義)
df_2 = df_1.pivot_table(index='fs_quarter_index', columns='fs_quarter_year', values='fs_roe' )
df_2.head()
輸出:
(由于财報資料沒有類似月份的列,我們選擇的時間也相對較短,本圖美觀度有所欠缺,不過重在總結方法)
現在使用pivot_table函數,我們可以建立一個Heat Maps,顯示在特定年份的特定季度特定股票的淨資産收益率(fs_roe)。為此,我們将輸入季度(fs_quarter_index)作為index參數的值。index屬性對應于行。接下來,我們需要将輸入年份(fs_quarter_year)作為列參數。最後對于values參數,我們将輸入淨資産收益率(fs_roe)。執行以下代碼:
sns.heatmap(df_2)
結果如下
從結果可以明顯看出,該股票在這段時間裡淨資産收益率的變化
有時候,您會發現方框或單元格是重疊的,單元格邊界之間的差別不是很清楚。要在單元格之間建立清晰的邊界,可以使用linecolor和linewidths參數。看看下面的代碼:
sns.heatmap(df_2, linecolor='blue', linewidth=1)
在上面的代碼中,我們輸入了“blue”作為linecolor參數的值,而line width參數被設定為1。在輸出中,您将看到每個單元格的藍色邊界:
如果需要更厚的邊界,可以增加linewidth參數的值。
Cluster Map
除了Heat Map,另一個常用的矩陣圖是Cluster Map。Cluster Map基本上使用層次聚類來對矩陣的行和列進行聚類。
讓我們繪制一個Cluster Map,表示在特定季度和特定年份的淨資産收益率。執行以下代碼:
df_3 = df_1[['fs_quarter_index','fs_roe','fs_quarter_year']]
df_4 = df_3.pivot_table(index='fs_quarter_year', columns='fs_quarter_index', values='fs_roe')
sns.clustermap(df_4)
要繪制叢集映射,需要使用clustermap函數,與heat map函數一樣,傳遞的資料集應該具有行和列的有意義的标題。上面代碼的結果是這樣的:
在輸出中,您可以看到根據特定季度和特定年份聚集起來的淨資産收益率。
至此,我們結束了關于矩陣圖的讨論。在下一節中,我們将開始讨論Seaborn庫的網格功能。
Seaborn網格
Seaborn中的網格允許我們根據圖中使用的特性操作子圖。
Pair Grid
在本系列文章的第1部分中,我們了解了如何使用pair plot繪制資料集中數字列的所有可能組合的散點圖。
現在讓我們在上述代碼的基礎上繪制Pair Plot。執行以下代碼:
df_5 = df[['fs_account_payable','fs_account_receivable','fs_capital_reserves','fs_construction_in_process','fs_undistributed_profit']]
sns.pairplot(df_5)
該代碼輸出是這樣的:
現在我們來畫Pair Grid看看Pair Grid和Pair Plot的差別。要建立對網格,隻需将資料集傳遞給PairGrid函數,如下所示:
sns.PairGrid(df_5)
在輸出中,您可以看到空網格。這就是pair grid函數的作用。它傳回資料集中所有特性的空網格集。
接下來,您需要對pair grid函數傳回的對象調用map函數,并将您希望在網格上繪制的繪圖類型傳遞給它。讓我們用對網格繪制一個散點圖。
df_5 = df_5.dropna()
df_6 = sns.PairGrid(df_5)
df_6.map(plt.scatter)
輸出是這樣的:
您可以在看到df_5中所有列分别作x、y軸的散點圖。
還可以在同一對網格上繪制不同類型的圖。例如,如果您想在對角線上繪制“分布”圖,在對角線的上半部分繪制“kdeplot”圖,在對角線的下半部分繪制“散點”圖,那麼您可以分别使用map_diag、map_upper和map_lower函數。将繪制的繪圖類型作為參數傳遞給這些函數。看看下面的代碼:
grids = sns.PairGrid(df_5)
grids.map_diag(sns.distplot)
grids.map_upper(sns.kdeplot)
grids.map_lower(plt.scatter)
代碼結果如下:
從上面的圖像中可以看出pair grid函數的真正威力。對角線上是分布圖,上半部分是核密度圖,下半部分是散點圖。
Facet Grids
Facet Grid用于将兩個或兩個以上的分類特征與兩個或兩個以上的數字特征進行繪圖。讓我們畫一個 Facet Grid來展示這幾個統計量兩兩之間的關系。
在本節中,我們将再次使用财報資料的部分列。執行以下代碼加載資料集:
df_6 = df[['fs_quarter_index','fs_roe','fs_quarter_year','fs_account_payable','fs_account_receivable','fs_capital_reserves','fs_construction_in_process','fs_undistributed_profit']]
df_6.head()
要繪制Facet Grid,使用FacetGrid()函數。函數的第一個參數是資料集,第二個參數col指定要在列上繪圖的特性,而row參數指定行上的特性。函數的作用是:傳回一個對象。與pair grid類似,您可以使用map函數指定要繪制的繪圖類型。
執行以下腳本:(winsorize函數将df_6進行去極值處理,目的是使得結果更加具有表現力)
def winsorize(df, width=3):
df = df.copy()
factor_columns = set(df.columns).difference(['date','instrument'])
for factor in factor_columns:
mean = df[factor].mean()
sigma = df[factor].std()
df[factor] = df[factor].clip(mean-width*sigma,mean+width*sigma)
return df
df_6 = winsorize(df_6)
grid = sns.FacetGrid(data=df_6, col='fs_quarter_year', row='fs_quarter_index')
grid.map(sns.distplot, 'fs_roe')
在上面的代碼中,我們在小平面網格上繪制了淨資産收益率分布圖。輸出是這樣的:
從輸出中,您可以看到4×9個圖,單個圖上展示了各個股票在特定年份特定季度的淨資産收益率(fs_roe)的分布,這由FacetGrid()函數指定。
對于不同的子圖之間,子圖的位置決定了該子圖的時間:第一行第一列的圖為2009年第一季度的淨資産收益率的分布圖,以此類推
除了為一個特征繪制分布圖外,我們還可以繪制包含面網格上兩個特征的散點圖。
例如,下面的代碼為年份和季度繪制了應付賬款(fs_account_payable)和資本公積金(fs_capital_reserves)的散點圖。
grid = sns.FacetGrid(data=df_6, col='fs_quarter_year', row='fs_quarter_index')
grid.map(sns.scatterplot, 'fs_account_payable','fs_capital_reserves')
輸出結果如下:
回歸圖
回歸圖,顧名思義,是用來進行兩個或多個變量之間的回歸分析。
在這一節中,我們将研究線性模型圖,它根據資料繪制出兩個變量之間的線性關系以及最佳拟合回歸線。
為了繪制線性模型,使用lmplot()函數。第一個參數是要在x軸上繪制的特征,第二個變量是要在y軸上繪制的特征。最後一個參數是資料集。執行以下代碼:
sns.lmplot(x='fs_account_payable', y='fs_capital_reserves', data=df_6)
您還可以根據分類特征繪制多個線性模型。特性名作為值傳遞給hue參數。例如,如果要繪制不同季度的時候應付賬款(fs_account_payable)和資本公積金(fs_capital_reserves)之間關系的多個線性模型,根據不同季度的情況,可以使用lmplot函數如下:
sns.lmplot(x='fs_account_payable', y='fs_capital_reserves', data=df_6,hue='fs_quarter_index')
結果如下
從輸出可以看出,對于理想切割的鑽石,克拉與價格之間的線性關系是最陡的,而對于合理切割的鑽石,線性模型是最淺的。
除了為不同色調的cut feature繪制資料外,我們還可以為每個cut繪制一個plot。為此,需要将列名傳遞給col屬性。看看下面的腳本:
sns.lmplot(x='fs_account_payable', y='fs_capital_reserves', data=df_6,col='fs_quarter_index')
在輸出中,您将看到鑽石資料集的cut列中的每個值都有一個單獨的列,如下所示:
您還可以使用aspect和size參數更改繪圖的大小和縱橫比。看看下面的代碼:
sns.lmplot(x='fs_account_payable', y='fs_capital_reserves', data=df_6,col='fs_quarter_index',aspect = 0.5,size = 8)
aspect參數定義寬度和高度之間的縱橫比。長寬比為0.5意味着寬度是輸出中所示高度的一半。
可以看出,圖的大小已經發生了變化,字型大小仍然很小。在下一節中,我們将看到如何控制Seaborn圖的字型和樣式。
圖像樣式
Seaborn庫提供了多種樣式選項。在本節中,我們将講解其中一些。
設定風格
函數的作用是:設定網格的樣式。您可以将darkgrid、whitegrid、dark、white和tick作為參數傳遞給set_style函數。
在本節中,我們将再次使用df_6。執行以下代碼以檢視darkgrid樣式。
df_6 = df_6.dropna()
sns.set_style('darkgrid')
sns.distplot(df_6['fs_roe'])
輸出如下:
在輸出中,您可以看到我們有帶有網格的黑色背景。讓我們看看whitegrid是什麼樣子。執行以下代碼:
sns.set_style('whitegrid')
sns.distplot(df_6['fs_roe'])
輸出如下:
現在你可以看到我們仍然有網格在背景中,但深灰色的背景是不可見的。我建議您嘗試使用其他選項,看看哪種風格适合您。
改變圖大小
由于Seaborn在背景使用Matplotlib函數,您可以使用Matplotlib的pyplot包來更改圖形大小,如下圖所示:
plt.figure(figsize=(8,4))
sns.distplot(df_6['fs_roe'])
在上面的代碼中,我們将情節的寬度和高度分别設定為8英寸和4英寸。上面腳本的輸出是這樣的:
設定 Context
您可以使用theset_context()函數,并将poster作為惟一的屬性傳遞給它,如下所示:
sns.set_context('poster')
sns.distplot(df_6['fs_roe'])
在輸出中,您應該看到一個符合海報标準的圖,如下所示。例如,您可以看到字型比正常的圖形大得多。
小結
Seaborn庫是用于資料可視化的進階Python庫。本文是關于在Python中使用Seaborn實作資料可視化的系列文章的第2部分。在這篇文章中,我們看到了如何在Seaborn中繪制回歸圖和矩陣圖。我們還了解了如何更改繪圖樣式和使用網格函數來操作子圖。