計(jì)繪圖指南:從安裝到實(shí)戰(zhàn),輕松打造專業(yè)級(jí)數(shù)據(jù)可視化)
很多人第一次接觸Seaborn都是從被Matplotlib默認(rèn)樣式丑到開始的我也不例外。那會(huì)兒我寫Python數(shù)據(jù)分析已經(jīng)快兩年每次出圖都像在跟坐標(biāo)系、刻度、圖例打架一張看似簡單的銷售額按月份對(duì)比圖光調(diào)樣式就能耗掉半小時(shí)。后來一個(gè)做統(tǒng)計(jì)建模的同事甩給我一段代碼里面有一行import seaborn as sns我抱著試試看的心態(tài)跑了一下結(jié)果三行代碼出來的圖配色干凈、網(wǎng)格舒服、箱線圖自帶置信區(qū)間我當(dāng)時(shí)的第一反應(yīng)是這玩意兒怎么沒早點(diǎn)用。這篇文章不是Seaborn官方文檔的翻譯而是我從一個(gè)數(shù)據(jù)分析從業(yè)者的角度把Seaborn從seaborn庫下載安裝、環(huán)境配置到常用統(tǒng)計(jì)圖形繪制、樣式定制再到實(shí)戰(zhàn)中踩過的坑完整梳理一遍。適合已經(jīng)會(huì)Python基礎(chǔ)、用過一點(diǎn)Matplotlib但覺得圖能用但不好看的讀者也適合剛?cè)腴T想直接上手統(tǒng)計(jì)可視化的朋友。讀完你會(huì)明白Seaborn到底比Matplotlib好在哪、什么時(shí)候該用它、什么時(shí)候該回去用Matplotlib以及怎么把一張能看的圖變成一張能放進(jìn)報(bào)告里的圖。1. 從Matplotlib到Seaborn我為什么最終留下了它1.1 Matplotlib的痛用過的人都知道先別急著給我扣捧一踩一的帽子。Matplotlib作為Python可視化生態(tài)的地基到現(xiàn)在我依然經(jīng)常用它的地位是Seaborn無法替代的。但不可否認(rèn)在畫統(tǒng)計(jì)圖形這件事上Matplotlib默認(rèn)配置有幾個(gè)真實(shí)存在的痛點(diǎn)。第一個(gè)痛點(diǎn)是默認(rèn)審美。Matplotlib的默認(rèn)配色是藍(lán)色#1f77b4搭配橙色#ff7f0e單看不難看但用在數(shù)據(jù)分析里總有種實(shí)驗(yàn)室儀器界面的味道。坐標(biāo)軸默認(rèn)帶上下左右四條邊框線spine網(wǎng)格線默認(rèn)不開標(biāo)題和坐標(biāo)軸標(biāo)簽的字號(hào)也得手動(dòng)調(diào)整。這些東西不是不能調(diào)而是要反復(fù)調(diào)每次畫新圖都要重來一遍。第二個(gè)痛點(diǎn)更核心Matplotlib沒有統(tǒng)計(jì)圖形這個(gè)層面的抽象。它的API是按畫什么元素來組織的——line、scatter、bar、boxplot你得自己把數(shù)據(jù)規(guī)整成對(duì)應(yīng)的格式。數(shù)據(jù)分析里最常見的需求按類別分組后看分布差異用Matplotlib就得手動(dòng)算分組位置、手動(dòng)設(shè)置箱線圖的寬度和位置、手動(dòng)寫圖例代碼量很快就失控了。第三個(gè)痛點(diǎn)是探索性分析時(shí)的效率。探索性數(shù)據(jù)分析EDA講究快速、多角度、反復(fù)看任何一個(gè)圖形多花十行代碼都會(huì)打斷思路。用Matplotlib畫一張帶了分面facet的分組分布圖光布局代碼就夠喝一壺而Seaborn把這類高頻需求壓縮到了一行。1.2 Seaborn在設(shè)計(jì)層面做了什么不同的事Seaborn的定位從來不是Matplotlib替代品而是統(tǒng)計(jì)圖形的封裝層。它建立在Matplotlib之上但引入了一套完全不同的設(shè)計(jì)思路。我覺得可以總結(jié)成兩句話第一把統(tǒng)計(jì)圖形變成最高優(yōu)先級(jí)的API第二把美學(xué)判斷內(nèi)置化用戶不需要懂設(shè)計(jì)也能出圖好看。第一句話的具體表現(xiàn)是Seaborn的API是按數(shù)據(jù)關(guān)系組織的relplot管變量間關(guān)系displot管分布catplot管分類對(duì)比加上專門畫回歸圖的lmplot、regplot畫矩陣圖的heatmap和clustermap。你在拿到數(shù)據(jù)后只需要想清楚我要回答什么問題然后就能直達(dá)對(duì)應(yīng)的函數(shù)完全不用在幾百個(gè)底層繪圖函數(shù)里翻找。第二句話的表現(xiàn)是樣式系統(tǒng)的設(shè)計(jì)。Seaborn自帶的主題、調(diào)色板、網(wǎng)格背景、坐標(biāo)軸邊框處理背后是一整套視覺規(guī)范默認(rèn)狀態(tài)就是經(jīng)過設(shè)計(jì)的。它不會(huì)讓你畫出顏色刺眼網(wǎng)格亂飛的圖除非你手動(dòng)改壞。1.3 更美更簡單這四個(gè)字到底是怎么實(shí)現(xiàn)的標(biāo)題里說更美更簡單我得負(fù)責(zé)任地解釋一下這兩個(gè)詞的含義避免你把它理解成Seaborn能自動(dòng)產(chǎn)出藝術(shù)大片。更美不是說Seaborn會(huì)給你加濾鏡。它做的是視覺減負(fù)淺色背景、細(xì)網(wǎng)格線、克制的配色、語義明確的色彩映射、去掉了默認(rèn)的上下左右全邊框。人的視覺系統(tǒng)對(duì)信息層級(jí)清晰的畫面會(huì)天然覺得好看Seaborn做的是把數(shù)據(jù)以外的視覺噪音降到最低。更簡單也不只是代碼行數(shù)少。真正減負(fù)的是心智負(fù)擔(dān)——你不用記每個(gè)圖形函數(shù)的坐標(biāo)軸邏輯不用在每次畫圖前想這個(gè)圖要不要開網(wǎng)格、要不要調(diào)透明度這些決策被Seaborn替你做了。你只需要關(guān)心數(shù)據(jù)和業(yè)務(wù)問題。這種減負(fù)在長時(shí)間的分析工作里能節(jié)省大量精力這也是我最終把它留下的核心原因。2. seaborn庫下載與安裝幾個(gè)容易踩的坑2.1 安裝命令與版本選擇聊完動(dòng)機(jī)直接上實(shí)操。seaborn庫下載的渠道是PyPI標(biāo)準(zhǔn)安裝命令很簡單pip install seaborn如果你跟我一樣用conda管理Python環(huán)境也可以走conda渠道conda install seaborn這兩條命令的區(qū)別主要在依賴解析上。conda會(huì)把numpy、scipy、pandas、matplotlib這些依賴一起檢查一遍版本兼容性裝完之后幾乎不會(huì)出現(xiàn)seaborn裝了但某個(gè)依賴版本不對(duì)的問題pip則快一些但依賴沖突的風(fēng)險(xiǎn)稍高。如果你是在公司內(nèi)網(wǎng)或者離線環(huán)境安裝需要提前把對(duì)應(yīng)的whl安裝包下載好這個(gè)細(xì)節(jié)容易被新手忽略。版本選擇上我建議直接裝最新穩(wěn)定版。到今天Seaborn已經(jīng)從早年間的0.8、0.9走到了0.13系列API變化非常大。特別提醒一點(diǎn)網(wǎng)上大量舊教程里的sns.distplot()在0.11版本之后就被移除了現(xiàn)在是histplot或displot的天下。你要是照著老教程敲代碼大概率會(huì)直接報(bào)AttributeError: module seaborn has no attribute distplot這不是你代碼的問題是教程過時(shí)了。2.2 安裝成功卻在導(dǎo)入時(shí)翻車環(huán)境錯(cuò)位問題這大概是seaborn庫下載安裝環(huán)節(jié)最常見的翻車現(xiàn)場。我早期踩過一次終端里pip install seaborn提示Successfully installed然后興沖沖打開Jupyter一import直接ModuleNotFoundError: No module named seaborn。排查下來發(fā)現(xiàn)原因很蠢機(jī)器上有好幾個(gè)Python環(huán)境——系統(tǒng)自帶一個(gè)、Anaconda一個(gè)、某個(gè)IDE又自動(dòng)建了虛擬環(huán)境。pip默認(rèn)裝進(jìn)了其中一個(gè)而Jupyter用的解釋器是另一個(gè)兩邊根本不互通。所以裝完任何Python包我養(yǎng)成了一個(gè)習(xí)慣立刻在當(dāng)前要用的解釋器里跑一遍驗(yàn)證命令。python -c import seaborn; print(seaborn.__version__)輸出類似0.13.2這樣的版本號(hào)才算真正裝好。如果這一步都過了但在Jupyter里還報(bào)錯(cuò)那就要檢查Jupyter用的kernel指向哪個(gè)解釋器用jupyter kernelspec list查看必要時(shí)把這個(gè)kernel指向你的目標(biāo)環(huán)境。2.3 Matplotlib版本配套與導(dǎo)入順序Seaborn本質(zhì)上是Matplotlib上層的一層封裝所以Matplotlib的版本會(huì)影響Seaborn的實(shí)際表現(xiàn)。我在項(xiàng)目里遇到過一個(gè)小問題Matplotlib升到3.7之后用Seaborn畫的圖右側(cè)和上方總是多出邊框線后來查GitHub的issue才發(fā)現(xiàn)是新版Matplotlib對(duì)spine的默認(rèn)處理邏輯變了Seaborn在老版本里沒有適配這個(gè)變化升級(jí)Seaborn之后就正常了。這給我們一個(gè)教訓(xùn)不要在一個(gè)項(xiàng)目里頻繁升級(jí)Matplotlib除非你確認(rèn)項(xiàng)目里沒有依賴舊行為的代碼。另外導(dǎo)入順序上我也有個(gè)習(xí)慣先import matplotlib再import seaborn代碼里經(jīng)常這樣寫import matplotlib import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt把matplotlib放在seaborn前面在部分老版本組合下能避免奇怪的警告。其實(shí)seaborn導(dǎo)入時(shí)自己會(huì)加載matplotlib所以這個(gè)順序更多是為了代碼可讀性和潛在兼容性。提示如果你的pandas還停留在1.x老版本但seaborn裝的是0.12以上部分用到新版pandas特性的圖形功能可能會(huì)不穩(wěn)定。升級(jí)seaborn之前先看看它的依賴要求通常寫著需要pandas1.2之類的下限。3. 核心繪圖函數(shù)逐個(gè)拆解分布、關(guān)系與分類3.1 分布形態(tài)histplot與kdeplot不管是做探索分析還是建模前檢查第一步永遠(yuǎn)是看變量的分布。Seaborn在分布圖上給了一個(gè)非常實(shí)用的組合histplot畫直方圖kdeplot畫核密度估計(jì)曲線兩者還能疊加。import seaborn as sns import matplotlib.pyplot as plt tips sns.load_dataset(tips) sns.histplot(datatips, xtotal_bill, bins30, kdeTrue) plt.show()這一行代碼做的事其實(shí)不少它自動(dòng)讀取total_bill這列按30個(gè)分箱畫直方圖再疊加一條核密度曲線。我為什么喜歡加kdeTrue因?yàn)橹狈綀D的形狀受分箱數(shù)影響很大——bins設(shè)10和設(shè)50可能看起來像是兩個(gè)不同的分布。核密度曲線不依賴分箱能從連續(xù)的角度呈現(xiàn)整體趨勢(shì)。兩者一起看等于同時(shí)獲得兩種視角。如果數(shù)據(jù)量特別大幾萬行以上直方圖會(huì)變得很密我一般直接用kdeplot加fillsns.kdeplot(datadf, xamount, fillTrue, alpha0.6)fillTrue給密度曲線下方填充顏色alpha控制透明度出來的圖既有形態(tài)又不會(huì)顯得擁擠。3.2 變量關(guān)系scatterplot、lineplot的用法與默認(rèn)行為數(shù)據(jù)探索的第二類高頻問題是兩個(gè)變量之間什么關(guān)系。Seaborn的關(guān)系圖家族核心是relplot底層對(duì)應(yīng)scatterplot散點(diǎn)圖和lineplot折線圖。散點(diǎn)圖最典型的寫法是這樣sns.scatterplot(datatips, xtotal_bill, ytip, huetime, stylesex)這行代碼把消費(fèi)金額—小費(fèi)的散點(diǎn)畫出來同時(shí)用顏色區(qū)分用餐時(shí)段用點(diǎn)樣式區(qū)分性別。hue、style、size是Seaborn的三個(gè)視覺通道參數(shù)分別把數(shù)據(jù)列映射到顏色、點(diǎn)樣式、點(diǎn)大小上。這種列到視覺通道的映射方式讓單張圖可以承載多個(gè)維度是做多維分析時(shí)的利器。lineplot有個(gè)容易被忽略的默認(rèn)行為如果同一個(gè)x值對(duì)應(yīng)多個(gè)y值它不會(huì)把點(diǎn)直接連過去而是對(duì)這些y值計(jì)算均值和置信區(qū)間畫出一條帶誤差帶的曲線。這個(gè)設(shè)計(jì)在統(tǒng)計(jì)上是合理的但很多從Excel轉(zhuǎn)過來的人第一次看到那條淺色帶子會(huì)以為是圖花了。其實(shí)那是置信區(qū)間如果你不需要它設(shè)置errorbarNone老版本里是ciNone就可以關(guān)掉。3.3 分組對(duì)比boxplot、violinplot與catplot的選擇邏輯處理分類變量對(duì)比時(shí)我先說一個(gè)選圖原則看你想讓讀者關(guān)注什么信息。想看中位數(shù)和四分位范圍的差異用箱線圖想看整體分布形態(tài)和離群點(diǎn)用小提琴圖想看清每個(gè)樣本點(diǎn)的位置用蜂群圖或帶狀圖。Seaborn把這一族統(tǒng)一在catplot這個(gè)入口下通過kind參數(shù)切換。sns.boxplot(datatips, xday, ytotal_bill, huesex)箱線圖是最穩(wěn)的選擇信息表達(dá)非常標(biāo)準(zhǔn)箱子是中四分位范圍箱中的橫線是中位數(shù)胡須是上下邊緣散點(diǎn)是超出1.5倍四分位距的離群點(diǎn)。加上huesex之后這張圖直接就是一個(gè)二維分組對(duì)比橫軸是星期幾顏色區(qū)分性別一眼看出周五男性消費(fèi)更高且分布更廣。如果樣本量不大而且想看數(shù)據(jù)點(diǎn)全貌我偶爾會(huì)用violinplot疊加swarmplot。小提琴圖反映分布形狀蜂群圖精確展示每個(gè)樣本點(diǎn)兩者疊加信息密度很高做PPT時(shí)會(huì)很驚艷。但也要提醒一句這種疊加圖不適合給讀圖經(jīng)驗(yàn)不足的受眾信息太多反而容易看懵。3.4 相關(guān)性矩陣heatmap是探索期第一張圖拿到一份新數(shù)據(jù)集我習(xí)慣做的第一件事是畫相關(guān)性熱力圖。不管多少列先看看變量兩兩之間的相關(guān)系數(shù)能快速發(fā)現(xiàn)哪些特征高度相關(guān)、哪些變量和目標(biāo)最貼近為后續(xù)建模節(jié)省大量時(shí)間。corr tips.corr(numeric_onlyTrue) sns.heatmap(corr, annotTrue, cmapcoolwarm, squareTrue)annotTrue把相關(guān)系數(shù)數(shù)值直接寫在格子里省去讀者肉眼比對(duì)顏色深淺的工作量cmap選coolwarm這類發(fā)散型色帶因?yàn)橄嚓P(guān)系數(shù)有正負(fù)語義用冷暖色區(qū)分比用單一漸變色更直觀squareTrue讓格子保持正方形視覺更整齊。如果你希望把相似變量聚到一起再展示可以試試clustermap它會(huì)做層次聚類讓熱力圖的塊狀結(jié)構(gòu)更清晰。4. 樣式系統(tǒng)Seaborn憑什么比Matplotlib好看4.1 set_theme一個(gè)函數(shù)接管全局視覺風(fēng)格Seaborn好看這件事不是玄學(xué)它背后是一套完整的樣式體系。這套體系的核心是sns.set_theme()一個(gè)函數(shù)同時(shí)設(shè)置背景風(fēng)格、調(diào)色板、字號(hào)縮放、網(wǎng)格線和一堆內(nèi)部參數(shù)。sns.set_theme(stylewhitegrid, palettedeep, font_scale1.2)style的可選值有darkgrid、whitegrid、dark、white、ticks五種。我個(gè)人最常用whitegrid白色背景只保留橫向網(wǎng)格線。橫向網(wǎng)格給讀者提供參考基準(zhǔn)縱向網(wǎng)格則完全是噪音。darkgrid適合深色背景的演示場景white適合追求極簡的場合ticks會(huì)把刻度線顯式畫出來日常用得少。palette參數(shù)控制默認(rèn)調(diào)色板默認(rèn)是deep還有muted、bright、pastel、dark、colorblind幾套。這里我想多說一句colorblind這套它是專門為色覺異常人群設(shè)計(jì)的顏色區(qū)分度在經(jīng)過色弱模擬之后依然明顯。給公開場合準(zhǔn)備圖表時(shí)用它細(xì)節(jié)處體現(xiàn)的就是專業(yè)度。4.2 調(diào)色板從顏色難看到顏色有語義很多人畫的圖丑在配色上不是顏色不夠鮮艷而是顏色沒有語義邏輯。Seaborn在配色上做了兩件事內(nèi)置合理的調(diào)色板以及提供靈活的生成方式。如果需要手動(dòng)控制顏色color_palette是萬能入口sns.color_palette(husl, 8) # 分類變量8個(gè)色相均勻分布的顏色 sns.color_palette(coolwarm, 5) # 連續(xù)數(shù)值冷暖發(fā)散 sns.color_palette(RdBu_r, 7) # 相關(guān)性熱力圖常用藍(lán)紅反轉(zhuǎn)如果想讓整篇報(bào)告的顏色體系統(tǒng)一則把調(diào)色板綁定到全局sns.set_palette(ch:s.25,rot-.25, n_colors5)這串參數(shù)看起來嚇人其實(shí)很好理解ch是Seaborn基于感知均勻顏色空間的生成器s是彩度rot是色相旋轉(zhuǎn)。出來的顏色在保持協(xié)調(diào)的前提下有足夠區(qū)分度。我第一次用這招是在一次客戶報(bào)告里五條折線用了這套配色比之前隨便挑的紅黃藍(lán)綠看起來高級(jí)很多。4.3 context上下文同一張圖適配不同媒介sns.set_context()解決的是同一張圖在不同場景怎么顯示的問題。同樣一張圖在筆記本屏幕上看和投到大屏幕上需要的字號(hào)、線條粗細(xì)完全不一樣。Seaborn把場景抽象成了四種contextpaper、notebook、talk、poster分別對(duì)應(yīng)論文、筆記本、演講和海報(bào)。sns.set_context(talk)我寫分析代碼時(shí)用默認(rèn)的notebook出周報(bào)時(shí)切到talk字號(hào)和線寬整體變大投影儀上不費(fèi)眼。paper和poster平時(shí)用得少但做論文配圖的人會(huì)很需要paper它會(huì)把元素尺寸壓到最小適合印刷排版。4.4 樣式系統(tǒng)也有邊界全局設(shè)置和局部覆蓋樣式系統(tǒng)很好用但有個(gè)坑必須提醒set_theme是全局設(shè)置調(diào)用一次后后續(xù)所有圖——包括你直接寫Matplotlib代碼畫的圖——都會(huì)受影響。大多數(shù)情況下這是好事但在同一個(gè)notebook里如果前兩格設(shè)置了Seaborn主題后面某格用了Matplotlib的某種特殊樣式可能就會(huì)發(fā)現(xiàn)某些改動(dòng)不生效原因是rcParams被全局覆蓋了。所以我現(xiàn)在的做法是一個(gè)分析腳本里在最前面統(tǒng)一調(diào)用一次set_theme中途不再切換。如果確實(shí)需要某個(gè)局部圖的特殊樣式用sns.plotting_context()配合with語句實(shí)現(xiàn)局部上下文而不是全局改來改去。這個(gè)習(xí)慣幫我少踩了很多樣式相互干擾的坑。5. 一個(gè)完整實(shí)戰(zhàn)從原始數(shù)據(jù)到能直接放進(jìn)報(bào)告里的圖5.1 場景設(shè)定電商訂單數(shù)據(jù)分析的第一步理論講完來一個(gè)完整實(shí)戰(zhàn)。假設(shè)你是一個(gè)電商平臺(tái)的數(shù)據(jù)分析師拿到一張訂單表里面有訂單金額、用戶類型新客/老客、星期、下單渠道、支付時(shí)間間隔等字段老板讓你回答三個(gè)問題訂單金額整體是什么形態(tài)新老客戶的客單價(jià)有沒有明顯差異訂單金額和支付時(shí)間間隔有沒有關(guān)聯(lián)這種分析在真實(shí)業(yè)務(wù)里天天發(fā)生。為了方便復(fù)現(xiàn)我用Seaborn自帶的tips數(shù)據(jù)集來演示——它有消費(fèi)金額total_bill、小費(fèi)tip、星期day、是否吸煙smoker、時(shí)段time、用餐人數(shù)size結(jié)構(gòu)上和訂單表非常接近分析的完整套路可以直接平移到你自己的數(shù)據(jù)上。如果你網(wǎng)絡(luò)環(huán)境不穩(wěn)定、load_dataset拉不到數(shù)據(jù)把數(shù)據(jù)集存成本地CSV再pd.read_csv一樣能跑。5.2 第一張圖訂單金額分布第一個(gè)問題看分布直接畫直方圖加密度曲線sns.histplot(datatips, xtotal_bill, bins40, kdeTrue) plt.title(消費(fèi)金額分布)看到這張圖能立刻得出幾個(gè)結(jié)論金額右偏存在長尾大部分訂單集中在10到25美元區(qū)間。在業(yè)務(wù)上這直接意味著兩件事滿減優(yōu)惠的檔位應(yīng)該設(shè)在訂單集中區(qū)間附近才能覆蓋最大人群長尾訂單雖然少但單價(jià)高值得單獨(dú)做高客單運(yùn)營策略。這就是分布圖在業(yè)務(wù)決策里的實(shí)際價(jià)值。5.3 第二張圖新老客戶分組對(duì)比第二個(gè)問題要對(duì)比不同客戶群體。在tips數(shù)據(jù)里我用day作為分組用smoker作為第二分組維度畫箱線圖sns.boxplot(datatips, xday, ytotal_bill, huesmoker)這張圖的直接結(jié)論是周五的消費(fèi)中位數(shù)高于其他幾天并且非吸煙組的金額分布范圍更大。如果要寫進(jìn)周報(bào)我會(huì)把這張圖配上這樣一句解讀周五消費(fèi)顯著走高且非吸煙人群貢獻(xiàn)了更高方差。如果覺得箱線圖不夠直觀換成violinplot加swarmplot的疊加視圖沖擊力更強(qiáng)只是不適合給讀圖經(jīng)驗(yàn)不足的領(lǐng)導(dǎo)看——太過花哨反而會(huì)分散注意力。5.4 第三張圖連續(xù)變量的關(guān)系驗(yàn)證第三個(gè)問題考察兩個(gè)連續(xù)或準(zhǔn)連續(xù)變量的關(guān)系。tips數(shù)據(jù)里size是用餐人數(shù)和金額的關(guān)系其實(shí)更像分組對(duì)比。我選擇用strip圖展示sns.stripplot(datatips, xsize, ytotal_bill, jitterTrue)jitterTrue給同一x位置上的點(diǎn)加一點(diǎn)隨機(jī)抖動(dòng)避免大量點(diǎn)重合。圖上能清楚看到兩人用餐的訂單金額區(qū)間最大六人大桌的訂單金額反而下降——因?yàn)榇笞谰蹠?huì)往往人均低。這種洞察散點(diǎn)圖或者直接做數(shù)值計(jì)算也能得到但圖形化呈現(xiàn)給業(yè)務(wù)方時(shí)理解成本低很多。5.5 多圖組織、保存與輸出規(guī)范三個(gè)問題回答完最后要把圖組織成一張可以放進(jìn)報(bào)告的整體看板。Seaborn的圖本質(zhì)上仍是Matplotlib的Figure和Axes對(duì)象所以我直接用plt.subplots創(chuàng)建畫布再把Seaborn的圖畫到指定子圖上。fig, axes plt.subplots(2, 2, figsize(12, 8)) sns.histplot(datatips, xtotal_bill, bins40, kdeTrue, axaxes[0, 0]) sns.boxplot(datatips, xday, ytotal_bill, huesmoker, axaxes[0, 1]) sns.stripplot(datatips, xsize, ytotal_bill, jitterTrue, axaxes[1, 0]) axes[1, 1].axis(off) plt.tight_layout() plt.savefig(analysis_dashboard.png, dpi200) plt.show()這里有一個(gè)我踩過的坑catplot這種figure-level函數(shù)會(huì)自己創(chuàng)建新的Figure不方便直接塞進(jìn)subplots布局里所以在多圖組合時(shí)應(yīng)該用histplot、boxplot、stripplot這類axes-level函數(shù)配合ax參數(shù)精確控制位置。保存用savefigdpi我一般設(shè)200兼顧顯示清晰度和文件大小。到這里一份從原始數(shù)據(jù)到可直接匯報(bào)的統(tǒng)計(jì)圖形的完整流程就跑通了。6. Seaborn的邊界什么情況下該回到Matplotlib6.1 靈活性受限需要像素級(jí)控制時(shí)的應(yīng)對(duì)我必須坦誠地講Seaborn省心省力的代價(jià)是靈活性受限。舉個(gè)具體的例子你想給散點(diǎn)圖上每個(gè)點(diǎn)添加自定義文字標(biāo)簽或者把圖例精確地放到畫布右下角某個(gè)坐標(biāo)這在Matplotlib里是常規(guī)操作但在Seaborn的封裝下就得先拿到Axes對(duì)象再調(diào)用底層的Matplotlib方法。這里我強(qiáng)烈推薦一種混合編程方式Seaborn負(fù)責(zé)畫統(tǒng)計(jì)圖主體Matplotlib負(fù)責(zé)微調(diào)細(xì)節(jié)。因?yàn)镾eaborn所有axes-level繪圖函數(shù)都返回一個(gè)Axes對(duì)象你可以對(duì)這個(gè)對(duì)象無縫繼續(xù)操作ax sns.boxplot(datatips, xday, ytotal_bill) ax.axhline(tips[total_bill].mean(), colorred, linestyle--, linewidth1.5, label整體均值) ax.legend()這種Seaborn畫骨架、Matplotlib填細(xì)節(jié)的模式我?guī)缀趺刻於荚谟媚芡瑫r(shí)拿到兩者最大的好處。6.2 大數(shù)據(jù)量下的性能瓶頸Seaborn在幾萬行數(shù)據(jù)上很流暢但數(shù)據(jù)量到了幾十萬甚至幾百萬行畫散點(diǎn)圖就會(huì)出現(xiàn)明顯的延遲圖像上的點(diǎn)密密麻麻完全沒法看。這不是bug而是把所有點(diǎn)都畫出來這個(gè)思路本身就不適合大數(shù)據(jù)。我的做法是降維而不是硬畫要么對(duì)數(shù)據(jù)做抽樣比如df.sample(n10000)要么改用密度類圖形比如用kdeplot畫二維密度熱力或者用hist2d做分箱統(tǒng)計(jì)??梢暬髷?shù)據(jù)的核心不是畫出每一個(gè)數(shù)據(jù)點(diǎn)而是用合理的方式呈現(xiàn)數(shù)據(jù)的整體結(jié)構(gòu)。抽樣之后在標(biāo)題里注明樣本量既保證透明又不犧牲性能這個(gè)技巧在真實(shí)項(xiàng)目里很實(shí)用。6.3 什么時(shí)候直接選Matplotlib一些場景Seaborn確實(shí)幫不上忙需要不規(guī)則子圖布局的時(shí)候比如一張大圖周圍排好幾張小圖需要非常規(guī)坐標(biāo)系的時(shí)候比如極坐標(biāo)圖、3D圖需要精細(xì)控制文本排版、數(shù)學(xué)公式渲染的出版級(jí)圖表。這些場景我都是直接用Matplotlib甚至用更底層的方案。我的選擇標(biāo)準(zhǔn)很簡單先想清楚這個(gè)圖是給誰看的、要表達(dá)什么統(tǒng)計(jì)語義。如果語義明確、信息層是常規(guī)的分布/關(guān)系/對(duì)比用Seaborn能省一半時(shí)間如果這個(gè)圖要做高度定制、走向非常規(guī)那就回到Matplotlib。兩者是互補(bǔ)關(guān)系就像寫字用簽字筆、畫素描用鉛筆工具跟隨需求而不是反過來。最后再分享一個(gè)我個(gè)人積累的小經(jīng)驗(yàn)。很多新手學(xué)Seaborn時(shí)會(huì)冒出把所有函數(shù)參數(shù)都背下來的念頭千萬別這么做我也做不到。真正實(shí)用的辦法是記住三個(gè)統(tǒng)一入口——displot、relplot、catplot以及三個(gè)視覺映射參數(shù)——hue、style、size剩下的按需查文檔。Seaborn的官方文檔做得相當(dāng)好每個(gè)函數(shù)都有示例圖和完整代碼你把數(shù)據(jù)換成自己的改改參數(shù)名基本就能跑通。還有一個(gè)我看了很多年圖的習(xí)慣畫完圖不要急著保存先盯著看五秒問自己三個(gè)問題——這張圖信息完整嗎視覺層級(jí)清楚嗎顏色是否存在誤導(dǎo)性如果三個(gè)答案都是肯定的它才是一張合格的統(tǒng)計(jì)圖。工具只是手段清晰、誠實(shí)、有洞察的可視化才是這份工作真正值錢的地方。