做者|Bex Tuychiev
編譯|VK
來源|Towards Datas Sciencehtml
本文的目標是讓你對使用Seaborn的relplot()函數繪製統計圖有必定的瞭解。node
當我開始學習數據可視化時,我第一次被介紹到Matplotlib。它是一個如此巨大的庫,你幾乎能夠看到任何與數據相關的東西。正是這種廣闊的空間,令人們可以以多種方式創造一個單一的圖表。python
雖然它的靈活性對於經驗豐富的科學家來講是理想的,但做爲一個初學者,要區分這些方法之間的代碼對我來講簡直是一場噩夢。做爲一名程序員,我甚至考慮過使用Tableau的無代碼接口,這一點我深感羞愧。我想要一個易於使用的東西,同時,使我可以建立那些其餘人(在代碼中)正在製做的酷圖。git
我在學生階段瞭解了Seaborn,最後找到了個人選擇。我對數據可視化的黃金法則理解是「若是你能在Seaborn作的話,就在Seaborn作」。它比其對應的Matplotlib提供了許多優點。程序員
首先,它很是容易使用。只需幾行代碼就能夠建立複雜的繪圖,而且使用內置樣式仍然可使其看起來很漂亮。其次,它與Pandas數據幀配合得很是好,這正是做爲數據科學家所須要的。github
最後但並不是最不重要的是,它構建在Matplotlib自己之上。這意味着你將享受Mpl提供的大部分靈活性,同時仍將代碼語法保持在最低限度。shell
Seaborn將其全部API分爲三類:繪製統計關係、可視化數據分佈和分類數據繪圖。Seaborn提供了三個高級函數,它們包含了它的大部分特徵,其中之一是relplot()。機器學習
relplot()能夠可視化定量變量之間的任何統計關係。在本文中,咱們將介紹這個函數的幾乎全部特性,包括如何建立子圖等等。函數
獲取此GitHub repo上文章的notebook和示例數據:https://github.com/BexTuychiev/medium_stories/tree/master/learn_one_third_of_seaborn_relplot工具
# 加載必要的庫 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import numpy as np # 繪製漂亮的圖形,避免模糊的圖像 %config InlineBackend.figure_format = 'retina' # 設置環境 sns.set_context('notebook') # 忽略警告 import warnings warnings.filterwarnings('ignore') # 啓用多個單元輸出 from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = 'all'
咱們以sns的縮寫導入Seaborn。你可能一直在想,爲何它不被縮寫爲sb。好吧,看看這個:它的別名來自電視劇《The West Wing》中的一個虛構人物Samuel Norman Seaborn。這是一個開玩笑的首字母縮寫。
對於示例數據,我將使用Seaborn的一個內置數據集和一個我從Kaggle下載的數據集。你能夠經過這個連接獲得它:https://www.kaggle.com/dgawlik/nyse/download
# 加載示例數據 cars = sns.load_dataset('mpg') stocks = pd.read_csv('data/prices-split-adjusted.csv', parse_dates=['date'], index_col=0)
第一個數據集是關於汽車的數據,包括髮動機、車型等。第二個數據集提供了500多家公司的紐約股票價格信息。
cars.head() cars.info() cars.describe()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 398 entries, 0 to 397 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 mpg 398 non-null float64 1 cylinders 398 non-null int64 2 displacement 398 non-null float64 3 horsepower 392 non-null float64 4 weight 398 non-null int64 5 acceleration 398 non-null float64 6 model_year 398 non-null int64 7 origin 398 non-null object 8 name 398 non-null object dtypes: float64(4), int64(3), object(2) memory usage: 28.1+ KB
stocks.head() stocks.info()
<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 851264 entries, 2016-01-05 to 2016-12-30 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 symbol 851264 non-null object 1 open 851264 non-null float64 2 close 851264 non-null float64 3 low 851264 non-null float64 4 high 851264 non-null float64 5 volume 851264 non-null float64 dtypes: float64(5), object(1) memory usage: 45.5+ MB
兩個數據集中都有一些空值。咱們目的是演示,咱們就能夠放心的丟棄它們。
cars.dropna(inplace=True) stocks.dropna(inplace=True)
專業提示:讓你的數據集儘量的整潔,這樣Seaborn才能表現出色。確保每一行都是一個觀察值,每一列都是一個變量。
relplot
繪散點圖讓咱們從散點圖開始。散點圖是用來找出變量之間的模式和關係的最好和最普遍使用的圖之一。
這些變量一般是定量的,例如測量值、一天中的溫度或任何數值。散點圖將x和y值的每一個元組可視化爲一個點,而且該圖將造成一個點雲。這些類型的圖是人眼探測模式和關係的理想選擇。
你可使用sb(我將從如今開始縮寫爲sb)的內置scatterplot()函數建立散點圖。可是這個函數缺乏relplot()中版本所提供的靈活性。讓咱們看一個使用relplot()的示例。
利用汽車數據集,咱們想知道重型汽車是否具備更大的馬力。因爲這兩個特徵都是數值型的,咱們可使用散點圖:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter');
函數具備參數x、y和data參數,分別指定要在X、Y軸上繪製的值以及它應該使用的數據。咱們使用kind參數指定它應該使用散點圖。實際上,默認狀況下,它被設置爲scatter。
從圖表來看,能夠解釋爲較重的汽車確實有更大的馬力。很明顯,還有更多的汽車重量在1500到3000之間,馬力50-110。
在前面的圖的基礎上,如今咱們還想添加一個新變量。讓咱們看看重車是否有更大的排量(他們能儲存多少燃料)。理想狀況下,咱們但願將此變量繪製爲點的大小:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement');
使用size參數來改變相對於第三個變量的點大小。只需將列名做爲字符串傳遞,就能夠進行設置,就像咱們的示例中同樣。此圖顯示了重量和發動機尺寸之間的明確關係。可是,你能夠在中心看到一些不符合趨勢的點。
重要的是傳遞一個數值變量,它將具備較少的「值週期」。若是太多的話,你的眼睛會很難理解這些事情。若是咱們用第三個變量weight建立上面的圖,你能夠看到:
sns.relplot(x='displacement', y='horsepower', data=cars, kind='scatter', size='weight');
正如你所見,趨勢並不明顯,很難區分大小。
也能夠將顏色標記用於散點圖中的第三個變量。它也很是簡單,就像點大小同樣。假設咱們還想將加速度(汽車達到60英里/小時(秒)的時間)編碼爲點顏色:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration');
從圖中,咱們能夠看到數據集中一些速度最快的汽車(較暗的點)馬力較低,但重量也較輕。注意,咱們使用hue參數來編碼顏色。顏色根據傳遞給此參數的變量類型而變化。若是咱們傳遞origin列,它是一個範疇變量,那麼它將有三個顏色標記,而不是一個連續的(從亮到暗)色調:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='origin');
專業提示:注意輸入到hue參數的變量類型。類型能夠徹底更改結果。
若是你不喜歡默認調色板(默認狀況下很是好),能夠輕鬆自定義:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest');
將palette參數設置爲你本身的顏色映射。可在此處找到可用選項板的列表:http://seaborn.pydata.org/tutorial/color_palettes.html
讓咱們回到第一個圖。咱們繪製了重量與馬力的散點圖。如今,讓咱們添加origin列做爲第三個變量:
sns.relplot(x='weight', y='horsepower', data=cars, hue='origin');
雖然顏色在這張圖中增長了一層額外的信息,但在更大的數據集中,可能很難區分點羣中的顏色。爲了更清晰起見,咱們將點的樣式添加到繪圖中:
sns.relplot(x='weight', y='horsepower', data=cars, hue='origin', style='origin');
好一點了。改變點的樣式和顏色是很是有效的。若是咱們只使用點的樣式來指定原點,看看會發生什麼:
sns.relplot(x='weight', y='horsepower', data=cars, style='origin');
提示:將色調和樣式參數結合使用,可使繪圖更加清晰。
咱們去掉了色調的參數,這使得咱們的圖表更難理解。若是不喜歡默認顏色,你能夠更改:
首先,你應該建立一個字典,將各個顏色映射到每一個類別。請注意,該字典的鍵應該與圖例中的名稱相同。
hue_colors = {'usa': 'red', 'japan': 'orange', 'europe': 'green'} sns.relplot(x='weight', y='horsepower', data=cars, hue='origin', style='origin', palette=hue_colors);
從圖中能夠看出,咱們數據集中的大部分汽車都來自美國。
讓咱們再次回到咱們的第一個例子。讓咱們再畫一次,但要增長一點透明度:
sns.relplot(x='weight', y='horsepower', data=cars, alpha=0.6);
咱們使用alpha參數來設置點的透明度。它接受0到1之間的值。0是徹底透明的,1是徹底不透明的。當你有一個大的數據集而且你想找出圖中的簇或組時,它是一個很是有用的特性。下降透明度時,圖中有許多圓點的部分將變暗。
在Seaborn也可使用子圖。我之因此使用relplot()而不是scatterplot(),由於它不能建立一個子圖。
因爲relplot是一個圖形級別的函數,它生成一個FacetGrid(一個由多個繪圖組成的網格)對象,而scatterplot()只打印到一個matplotlib.pyplot.Axes(單個繪圖)不能轉換爲子圖的對象:
fg = sns.relplot() print(type(fg)) plot = sns.scatterplot() print(type(plot)) <class 'seaborn.axisgrid.FacetGrid'> <class 'matplotlib.axes._subplots.AxesSubplot'>
讓咱們看一個例子,咱們想在其中使用子圖。在上面的其中一個圖中,咱們將4個變量編碼到一個單獨的圖中(重量,馬力,排量和加速度)。如今,咱們還要添加汽車的原產地。爲了使信息更易於解釋,咱們應該將其劃分爲子圖:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin');
這一次,咱們添加了一個新參數col,指出咱們但願在列中建立子圖。這些類型的子區間很是有用,由於如今很容易看到第五個變量的趨勢。順便說一句,傳遞給col的變量應該是離散的,這樣才能起做用。此外,SB在一行中顯示列。若是有多個類別須要繪製,咱們不但願這樣。讓咱們看一個使用咱們的數據的用例,儘管它的類別較少:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin', col_wrap=2);
col_wra參數告訴SB咱們但願一行中有多少列。
還能夠指定列中類別的順序:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin', col_order=['japan', 'europe', 'usa']);
也能夠在行中顯示相同的信息:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', row='origin');
若是有不少類別,那麼使用行並非頗有用,最好仍是堅持使用列。你能夠再次使用row_order指定行的順序。
關係圖的另外一種常見類型是線圖。而在散點圖中,每一個點都是一個獨立的觀察點,在線圖中,咱們繪製了一個變量和一些連續變量,一般是一段時間。咱們的第二個樣本數據集包含2010年至2016年跟蹤的501家公司的紐約證券交易所數據。
爲了便於說明,讓咱們觀察給定時間段內全部公司的收盤價。因爲涉及日期,所以線條圖是此任務的最佳視覺類型:
專業提示:若是數據集中有一個日期列,請將其設置爲日期類型,而後使用set_index()函數將其設置爲索引。或使用pd.read_csv(parse_dates=['date_column'], index_col='date_column')。它將容許你繪製線圖,並使日期的設置更容易。
對於線圖,咱們再次使用relplot()並將kind設置爲line。這將繪製第二個連續變量(一般是時間)上跟蹤的單個變量。
sns.relplot(x=stocks.index, y='close', data=stocks, kind='line');
咱們能夠看到明顯的趨勢。全部公司的股票在給定的時間段內都在增加。藍色較深的線表明6年來追蹤的全部公司收盤價的平均值。
SB會自動增長一個置信區間,若是對一個點有多個觀測會添加那條線周圍的陰影區域,稍後會詳細介紹。如今,讓咱們把數據集中到3家公司:
am_ap_go = stocks[stocks['symbol'].isin(['AMZN', 'AAPL', 'GOOGL'])] am_ap_go.shape (5286, 6)
如今,讓咱們經過將數據分組到三個公司來從新建立上面的線圖。這將在同一繪圖中建立三條線,而不是一條:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', hue='symbol');
就像咱們在散點圖示例中所作的那樣,咱們使用hue參數在數據中建立子組。一樣,你必須將一個範疇變量傳遞到hue中。在這幅圖中,咱們能夠看到,在2016年以後,亞馬遜和谷歌的股價很是接近,而蘋果在整個期間都處於底部。如今,讓咱們看看咱們是如何將每一行與顏色區分開來的:
咱們使用style參數來指定每一行須要不一樣的線條樣式:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', hue='symbol', style='symbol');
好吧,這可能不是不一樣線條風格的最佳例子,由於觀察是針對每一天的,並且很是緊湊。讓咱們僅對2015-2016年期間進行子集劃分,並繪製相同的線圖:
am_ap_go_subset = am_ap_go.loc['2015-01-01':'2015-12-31'] sns.relplot(x=am_ap_go_subset.index, y='close', data=am_ap_go_subset, kind='line', hue='symbol', style='symbol');
如今線條風格更清晰了。你可能會說,這好像沒什麼分別。可是當你有一個圖表,它的線很是緊湊的話,這可能能夠幫助你理解某些東西。
當你有一個較小的數據集而且想要建立一個線圖時,用點標記來標記每一個數據點可能會頗有用。對於咱們較小的股票價格分佈數據來講仍然是很是緊張的。因此,讓咱們用一個更小的時間段,來看看如何使用點標記:
smaller_subset = am_ap_go_subset.loc["2015-01-01":"2015-03-01"] sns.relplot(x=smaller_subset.index, y='close', data=smaller_subset, kind='line', hue='symbol', style='symbol', markers=True) plt.xticks(rotation=60);
如今每行都有不一樣的標記。咱們將markers參數設置爲True以激活此功能。
接下來,咱們將探討在SB中計算線圖的置信區間。若是對一個點有多個觀測值,則會自動添加置信區間。
在咱們對這三家公司的數據中,每一天都有三個觀察結果:一個是亞馬遜,一個是谷歌,一個是蘋果。當咱們建立不帶子組(不帶色調參數)的線條圖時,默認狀況下,SB取這三個值的平均值:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line');
較暗的線表示這三家公司股價的平均值。陰影區域爲95%置信區間。這是很是巨大的,由於咱們的樣本數據只有三家公司。陰影區意味着95%的人的平均值在這個區間內。它代表了咱們數據的不肯定性。
例如,2017年,人口平均數在100到800之間。置信區間的範圍是巨大的。將ci參數設置爲「None」能夠關閉置信區間:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', ci=None);
或者,若是須要,能夠顯示標準誤差而不是置信區間。將ci參數設置爲sd:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', ci='sd');
也許這些參數對於咱們的示例數據不是頗有用,可是當你處理大量真實數據時,它們將很是重要。
最後一點:若是要爲線圖建立子圖,可使用相同的col和row參數。
最後,咱們完成了Seaborn的關係圖。線圖和散點圖是在數據海洋中發現洞察力和趨勢的很是重要的視覺輔助工具。所以,掌握它們是很重要的。儘量使用Seaborn來建立它們。
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方文檔:
http://sklearn123.com/
歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/