導(dǎo)讀:我們介紹過用matplotlib制作圖表的一些tips,感興趣的同學可以戳→純干貨:手把手教你用Python做數(shù)據(jù)可視化(附代碼)。matplotlib是一個相當?shù)讓拥墓ぞ?。你可以從其基本組件中組裝一個圖表:數(shù)據(jù)顯示(即繪圖的類型:線、條、框、散點圖、輪廓等)、圖例、標題、刻度標記和其他注釋。 在pandas中,我們可能有多個數(shù)據(jù)列,并且?guī)в行泻土械臉撕灐andas自身有很多內(nèi)建方法可以簡化從DataFrame和Series對象生成可視化的過程。另一個是seaborn,它是由Michael Waskom創(chuàng)建的統(tǒng)計圖形庫。seaborn簡化了很多常用可視化類型的生成。 導(dǎo)入seaborn會修改默認的matplotlib配色方案和繪圖樣式,這會提高圖表的可讀性和美觀性。即使你不適用seaborn的API,你可能更喜歡導(dǎo)入seaborn來為通用matplotlib圖表提供更好的視覺美觀度。 作者:Wes McKinney 本文摘編自《利用Python進行數(shù)據(jù)分析》(原書第2版),如需轉(zhuǎn)載請聯(lián)系我們 01 折線圖 Series和DataFrame都有一個plot屬性,用于繪制基本的圖型。默認情況下,plot()繪制的是折線圖(見圖9-13): In [ 60 ]: s = pd.Series(np.random.randn( 10 ).cumsum(), index = np.arange( 0 , 100 , 10 )) In [ 61 ]: s.plot() ▲圖9-13 簡單序列圖形 Series對象的索引傳入matplotlib作為繪圖的x軸,你可以通過傳入use_index=False來禁用這個功能。x軸的刻度和范圍可以通過xticks和xlim選項進行調(diào)整,相應(yīng)地y軸使用yticks和ylim進行調(diào)整。表9-3是plot的全部選項列表。本節(jié)我會介紹這些選項中的一些,其余你可以自行探索。 大部分pandas的繪圖方法,接收可選的ax參數(shù),該參數(shù)可以是一個matplotlib子圖對象。這使你可以更為靈活的在網(wǎng)格布局中放置子圖。 DataFrame的plot方法在同一個子圖中將每一列繪制為不同的折線,并自動生成圖例(見圖9-14): In [ 62 ]: df = pd.DataFrame(np.random.randn( 10 , 4 ).cumsum( 0 ), ....: columns = [ 'A' , 'B' , 'C' , 'D' ], ....: index = np.arange( 0 , 100 , 10 )) In [ 63 ]: df.plot() ▲圖9-14 簡單DataFrame繪圖 plot屬性包含了不同繪圖類型的方法族。例如,df.plot( )等價于df.plot.line( )。我們之后將會探索這些方法中的一部分。 要繪制的其他關(guān)鍵字參數(shù)會傳遞到相應(yīng)的matplotlib繪圖函數(shù),因此你可以通過了解更多的matplotlib的 API信息來進一步定制這些圖表。
▲表9-3 Series.plot方法參數(shù) DataFrame擁有多個選項,允許靈活地處理列;例如,是否將各列繪制到同一個子圖中,或為各列生成獨立的子圖。參考表9-4了解更多選項。
▲表9-4 02 柱狀圖 plot.bar()和plot.barh()可以分別繪制垂直和水平的柱狀圖。在繪制柱狀圖時,Series或DataFrame的索引將會被用作x軸刻度(bar)或y軸刻度(barh)(參考圖9-15): In [ 64 ]: fig, axes = plt.subplots( 2 , 1 ) In [ 65 ]: data = pd.Series(np.random.rand( 16 ), index = list ( 'abcdefghijklmnop' )) In [ 66 ]: data.plot.bar(ax = axes[ 0 ], color = 'k' , alpha = 0.7 ) Out[ 66 ]: <> 0x7fb62493d470 > In [ 67 ]: data.plot.barh(ax = axes[ 1 ], color = 'k' , alpha = 0.7 ) ▲圖9-15 水平柱狀圖和垂直柱狀圖 選項color='k'和alpha=0.7將柱子的顏色設(shè)置為黑色,并將圖像的填充色設(shè)置為部分透明。 在DataFrame中,柱狀圖將每一行中的值分組到并排的柱子中的一組。參考圖9-16: In [ 69 ]: df = pd.DataFrame(np.random.rand( 6 , 4 ), ....: index = [ 'one' , 'two' , 'three' , 'four' , 'five' , 'six' ], ....: columns = pd.Index([ 'A' , 'B' , 'C' , 'D' ], name = 'Genus' )) In [ 70 ]: df Out[ 70 ]: Genus A B C D one 0.370670 0.602792 0.229159 0.486744 two 0.420082 0.571653 0.049024 0.880592 three 0.814568 0.277160 0.880316 0.431326 four 0.374020 0.899420 0.460304 0.100843 five 0.433270 0.125107 0.494675 0.961825 six 0.601648 0.478576 0.205690 0.560547 In [ 71 ]: df.plot.bar() ▲圖9-16 DataFrame柱狀圖 請注意DataFrame的列名稱'Genus'被用作了圖例標題。我們可以通過傳遞stacked=True來生成堆積柱狀圖,會使得每一行的值堆積在一起(參考圖9-17): In [ 73 ]: df.plot.barh(stacked = True , alpha = 0.5 ) ▲圖9-17 DataFrame堆積柱狀圖 使用value_counts: s.value_counts().plot.bar()可以有效的對Series值頻率進行可視化。 回到本書之前使用的數(shù)據(jù)集,假設(shè)我們想要繪制一個堆積柱狀圖,用于展示每個派對在每天的數(shù)據(jù)點占比。使用read_csv載入數(shù)據(jù),并根據(jù)星期幾數(shù)值和派對規(guī)模進形成交叉表: In [ 75 ]: tips = pd.read_csv( 'examples/tips.csv' ) In [ 76 ]: party_counts = pd.crosstab(tips[ 'day' ], tips[ 'size' ]) In [ 77 ]: party_counts Out[ 77 ]: size 1 2 3 4 5 6 day Fri 1 16 1 1 0 0 Sat 2 53 18 13 1 0 Sun 0 39 15 18 3 1 Thur 1 48 4 5 1 3 # 沒有太多的1人和6人派對 In [ 78 ]: party_counts = party_counts.loc[:, 2 : 5 ] 之后,進行標準化以確保每一行的值和為1,然后進行繪圖(見圖9-18): # 標準化至和為1 In [ 79 ]: party_pcts = party_counts.div(party_counts. sum ( 1 ), axis = 0 ) In [ 80 ]: party_pcts Out[ 80 ]: size 2 3 4 5 day Fri 0.888889 0.055556 0.055556 0.000000 Sat 0.623529 0.211765 0.152941 0.011765 Sun 0.520000 0.200000 0.240000 0.040000 Thur 0.827586 0.068966 0.086207 0.017241 In [ 81 ]: party_pcts.plot.bar() ▲圖9-18 每天派對數(shù)量的百分比 你可以看到本數(shù)據(jù)集中的派對數(shù)量在周末會增加。 對于在繪圖前需要聚合或匯總的數(shù)據(jù),使用seaborn包會使工作更為簡單。現(xiàn)在讓我們看下使用seaborn進行按星期幾數(shù)值計算小費百分比(見圖9-19中的結(jié)果圖): In [ 83 ]: import seaborn as sns In [ 84 ]: tips[ 'tip_pct' ] = tips[ 'tip' ] / (tips[ 'total_bill' ] - tips[ 'tip' ]) In [ 85 ]: tips.head() Out[ 85 ]: total_bill tip smoker day time size tip_pct 0 16.99 1.01 No Sun Dinner 2 0.063204 1 10.34 1.66 No Sun Dinner 3 0.191244 2 21.01 3.50 No Sun Dinner 3 0.199886 3 23.68 3.31 No Sun Dinner 2 0.162494 4 24.59 3.61 No Sun Dinner 4 0.172069 In [ 86 ]: sns.barplot(x = 'tip_pct' , y = 'day' , data = tips, orient = 'h' ) ▲圖9-19 用錯誤欄按天顯示小費百分比 seaborn中的繪圖函數(shù)使用一個data參數(shù),這個參數(shù)可以是pandas的DataFrame。其他的參數(shù)則與列名有關(guān)。因為day列中有多個觀測值,柱子的值是tip_pct的平均值。柱子上畫出的黑線代表的是95%的置信區(qū)間(置信區(qū)間可以通過可選參數(shù)進行設(shè)置)。 seaborn.barplot擁有一個hue選項,允許我們通過一個額外的分類值將數(shù)據(jù)分離: In [ 88 ]: sns.barplot(x = 'tip_pct' , y = 'day' , hue = 'time' , data = tips, orient = 'h' ) ▲圖9-20 根據(jù)星期幾數(shù)值和時間計算的小費百分比 請注意seaborn自動改變了圖表的美觀性:默認的調(diào)色板、圖背景和網(wǎng)格線條顏色。你可以使用seaborn.set在不同的繪圖外觀中進行切換: In [ 90 ]: sns. set (style = 'whitegrid' ) 03 直方圖和密度圖 直方圖是一種條形圖,用于給出值頻率的離散顯示。數(shù)據(jù)點被分成離散的,均勻間隔的箱,并且繪制每個箱中數(shù)據(jù)點的數(shù)量。使用之前的小費數(shù)據(jù),我們可以使用Series的plot.hist方法制作小費占總費用百分比的直方圖(見圖9-21): In [ 92 ]: tips[ 'tip_pct' ].plot.hist(bins = 50 ) ▲圖9-21 小費百分比的直方圖 密度圖是一種與直方圖相關(guān)的圖表類型,它通過計算可能產(chǎn)生觀測數(shù)據(jù)的連續(xù)概率分布估計而產(chǎn)生。通常的做法是將這種分布近似為“內(nèi)核”的混合,也就是像正態(tài)分布那樣簡單的分布。因此,密度圖也被成為內(nèi)核密度估計圖(KDE)。plot.kde使用傳統(tǒng)法定混合法估計繪制密度圖(見圖9-22): In [ 94 ]: tips[ 'tip_pct' ].plot.density() ▲圖9-22 小費百分比密度圖 distplot方法可以繪制直方圖和連續(xù)密度估計,通過distplot方法seaborn使直方圖和密度圖的繪制更為簡單。作為例子,考慮由兩個不同的標準正態(tài)分布組成的雙峰分布(見圖9-23): In [ 96 ]: comp1 = np.random.normal( 0 , 1 , size = 200 ) In [ 97 ]: comp2 = np.random.normal( 10 , 2 , size = 200 ) In [ 98 ]: values = pd.Series(np.concatenate([comp1, comp2])) In [ 99 ]: sns.distplot(values, bins = 100 , color = 'k' ) ▲圖9-23 正態(tài)混合的標準化直方圖與密度估計 04 散點圖或點圖 點圖或散點圖可以用于檢驗兩個一維數(shù)據(jù)序列之間的關(guān)系。例如,這里我們從statsmodels項目中載入了macrodata數(shù)據(jù)集,并選擇了一些變量,之后計算對數(shù)差: In [ 100 ]: macro = pd.read_csv( 'examples/macrodata.csv' ) In [ 101 ]: data = macro[[ 'cpi' , 'm1' , 'tbilrate' , 'unemp' ]] In [ 102 ]: trans_data = np.log(data).diff().dropna() In [ 103 ]: trans_data[ - 5 :] Out[ 103 ]: cpi m1 tbilrate unemp 198 - 0.007904 0.045361 - 0.396881 0.105361 199 - 0.021979 0.066753 - 2.277267 0.139762 200 0.002340 0.010286 0.606136 0.160343 201 0.008419 0.037461 - 0.200671 0.127339 202 0.008894 0.012202 - 0.405465 0.042560 然后我們可以使用seaborn的reglot方法,該方法可以繪制散點圖,并擬合出一個條線性回歸線(見圖9-24): In [ 105 ]: sns.regplot( 'm1' , 'unemp' , data = trans_data) Out[ 105 ]: <> 0x7fb613720be0 > In [ 106 ]: plt.title( 'Changes in log %s versus log %s' % ( 'm1' , 'unemp' )) ▲圖9-24 seaborn回歸/散點圖 在探索性數(shù)據(jù)分析中,能夠查看一組變量中的所有散點圖是有幫助的; 這被稱為成對圖或散點圖矩陣。從頭開始繪制這樣一個圖是有點工作量的,所以seaborn有一個方便的成對圖函數(shù),它支持在對角線上放置每個變量的直方圖或密度估計值(結(jié)果圖見圖9-25): In [ 107 ]: sns.pairplot(trans_data, diag_kind = 'kde' , plot_kws = { 'alpha' : 0.2 }) ▲圖9-25 statsmodels macro數(shù)據(jù)的成對圖矩陣 你可能會注意到plot_ksw參數(shù),這個參數(shù)使我們能夠?qū)⑴渲眠x項傳遞給非對角元素上的各個繪圖調(diào)用。參考seaborn.pairplot的文檔字符串可以看到更多細節(jié)的設(shè)置選項。 05 分面網(wǎng)格和分類數(shù)據(jù) 如果數(shù)據(jù)集有額外的分組維度怎么辦?使用分面網(wǎng)格是利用多種分組變量對數(shù)據(jù)進行可視化的方式。seaborn擁有一個有效的內(nèi)建函數(shù)factorplot,可以簡化多種分面繪圖(見圖9-26): In [ 108 ]: sns.factorplot(x = 'day' , y = 'tip_pct' , hue = 'time' , col = 'smoker' , .....: kind = 'bar' , data = tips[tips.tip_pct <> 1 ]) ▲圖9-26 按星期幾數(shù)值/時間/是否吸煙劃分的小費百分比 除了根據(jù)'time'在一個面內(nèi)將不同的柱分組為不同的顏色,我們還可以通過每個時間值添加一行來擴展分面網(wǎng)格(見圖9-27): In [ 109 ]: sns.factorplot(x = 'day' , y = 'tip_pct' , row = 'time' , .....: col = 'smoker' , .....: kind = 'bar' , data = tips[tips.tip_pct <> 1 ]) ▲圖9-27 根據(jù)時間/是否吸煙分面后按星期幾數(shù)值劃分的小費百分比 factorplot 支持其他可能有用的圖類型,具體取決于你要顯示的內(nèi)容。 例如,箱形圖(顯示中位值,四分位數(shù)和異常值)可以是有效的可視化類型(圖9-28): In [ 110 ]: sns.factorplot(x = 'tip_pct' , y = 'day' , kind = 'box' , .....: data = tips[tips.tip_pct <> 0.5 ]) ▲圖9-28 根據(jù)星期幾數(shù)值繪制的小費百分比箱型圖 你可以使用更通用的seaborn.FacetGrid類創(chuàng)建自己的分面網(wǎng)格圖。 具體請查看更多的seaborn文檔。 06 其他Python可視化工具 和開源代碼一樣,在Python語言下創(chuàng)建圖形的選擇有很多(太多而無法一一列舉)。自從2010年以來,很多開發(fā)工作都集中在創(chuàng)建web交互式圖形上。借助像Bokeh和Plotly這樣的工具,在web瀏覽器中創(chuàng)建動態(tài)的、交互式圖像的工作現(xiàn)在已經(jīng)可以實現(xiàn)。 如果是創(chuàng)建用于印刷或網(wǎng)頁的靜態(tài)圖形,我建議根據(jù)你的需要使用默認的matplotlib以及像pandas和seaborn這樣的附加庫。 對于其他數(shù)據(jù)可視化要求,學習其他可用工具之一可能是有用的。我鼓勵你探索Python可視化生態(tài)系統(tǒng),因為它將持續(xù)增添新內(nèi)容并在未來進行更多創(chuàng)新。 關(guān)于作者:韋斯·麥金尼(Wes McKinney)是流行的Python開源數(shù)據(jù)分析庫pandas的創(chuàng)始人。他是一名活躍的演講者,也是Python數(shù)據(jù)社區(qū)和Apache軟件基金會的Python/C++開源開發(fā)者。目前他在紐約從事軟件架構(gòu)師工作。 |
|
來自: heii2 > 《大數(shù)據(jù)》