Seaborn(sns)官方文檔學習筆記(第六章 繪製數據網格)
繪製數據網格
在探索中等維度數據時,一個有用的方法是在數據集的不同子集上繪製相同繪圖的多個實例。這種技術有時被稱為「格子」或「格子」繪圖,它與「小倍數」的想法有關。 它允許觀看者快速提取大量關於複雜數據的信息。 Matplotlib可以很好地支持製作具有多個軸的圖形; seaborn建立在此之上,以將結構直接鏈接到數據集結構上進行繪製。
要使用這些功能,您的數據必須位於Pandas DataFrame中,並且必須採用Hadley Whickam稱為「整潔」數據的形式。 簡而言之,這意味著您的數據框架應該被結構化,使得每一列都是一個變數,每一行都是一個觀測。
對於高級使用,您可以直接使用本教程本部分中討論的對象,這將提供最大的靈活性。一些Seaborn功能(如lmplot(),factorplot()和pairplot())也在幕後使用。與其他Seaborn功能「Axes級別」不同,並且繪製在特定(可能已經存在的)matplotlib軸上,而無需其他操作的圖形,這些較高級別的功能在調用時創建一個數字,並且通常更嚴格地說明如何設置。在某些情況下,對於這些函數或其依賴的類的構造函數的參數將提供與圖形大小不同的介面屬性,如lmplot()的情況,您可以在其中設置每個方面的高度和縱橫比而不是整體尺寸。使用這些對象之一的任何函數總是在繪製之後返回,而且這些對象中的大多數都具有方便的方法來改變繪製,通常以更抽象和簡單的方式。
%matplotlib inlineimport numpy as npimport pandas as pdimport seaborn as snsfrom scipy import statsimport matplotlib as mplimport matplotlib.pyplot as pltsns.set(stylex="ticks")np.random.seed(sum(map(ord, "axis_grids")))
用FacetGrid子集數據
當您想要在數據集的子集內可視化變數的分布或多個變數之間的關係時,FacetGrid類很有用。 FacetGrid可以繪製最多三個維度:row,col和hue。前兩者與所得軸數有明顯的對應關係;將hue變數視為沿著深度軸的第三維,其中不同的級別用不同的顏色繪製。
通過使用數據框初始化FacetGrid對象和將形成網格的行,列或色調維度的變數的名稱來使用該類。 這些變數應該是分類的或離散的,然後變數的每個級別的數據將用於沿該軸的小平面。 例如,假設我們要檢查tips數據集中的午餐和晚餐之間的差異。
另外,lmplot()和factorplot()在內部使用這個對象,並且當它們被修改時,它們返回該對象,以便可以用於進一步的調整。
tips = sns.load_dataset("tips")tips.head()
total_billtipsexsmokerdaytimesize016.991.01FemaleNoSunDinner 2110.341.66MaleNoSunDinner 3221.013.50MaleNoSunDinner 3323.683.31MaleNoSunDinner 2424.593.61FemaleNoSunDinner 4
g = sns.FacetGrid(tips, col="time")
像這樣初始化網格設置了matplotlib圖形和軸,但並沒有繪製任何東西。
在此網格上可視化數據的主要方法是使用FacetGrid.map()方法,提供一個繪圖功能和數據框中變數的名稱來繪製。我們來看一下這些子集中提示的分布,使用直方圖。
g = sns.FacetGrid(tips, col="time")g.map(plt.hist, "tip");
此功能將繪製圖形並注釋軸,並在一個步驟中生成完成。 要做一個關係圖,只需傳遞多個變數名。可以提供關鍵字參數,將其傳遞給繪圖功能:
g = sns.FacetGrid(tips, col="sex", hue="smoker")g.map(plt.scatter, "total_bill", "tip", alpha=.7)g.add_legend();
有幾個選項可以控制可以傳遞給類構造函數的網格的外觀。
g = sns.FacetGrid(tips, row="smoker", col="time", margin_titles=True)g.map(sns.regplot, "size", "total_bill", color=".3", fit_reg=False, x_jitter=.1);
請注意,matplotlib API沒有正式支持margin_titles,並且在所有情況下都可能無法正常運行。 特別是,它目前不能用於圖形之外的注釋框。
通過提供每個圖形的高度以及縱橫比來達到設置圖形大小的目的。
g = sns.FacetGrid(tips, col="day", size=4, aspect=.5)g.map(sns.barplot, "sex", "total_bill");
在matplotlib大於1.4的版本中,可以傳遞在gridspec模塊中的參數,增加其尺寸來吸引注意力。當然,在每個方面可視化不同數量的組的數據集的分布時,這無疑是特別實用的。
titanic = sns.load_dataset("titanic")titanic = titanic.assign(deck=titanic.deck.astype(object)).sort_values("deck")g = sns.FacetGrid(titanic, col="class", sharex=False, gridspec_kws={"width_ratios": [5, 3, 3]})g.map(sns.boxplot, "deck", "age");
這裡,默認的順序來自於DataFrame中的書序。如果用於定義facets具有分類變數的類型,則會實用類別的順序。否則,facets將按照級別的順序排列。當然,也可以使用適當的*_order參數來指定任何平面維度的數據順序。
ordered_days = tips.day.value_counts().indexg = sns.FacetGrid(tips, row="day", row_order=ordered_days, size=1.7, aspect=4,)g.map(sns.distplot, "total_bill", hist=False, rug=True);
可以提供任何Seaborn調色板(即可以傳遞給color_palette()的參數),還可以使用將色調變數中值的名稱映射到有效的matplotlib顏色的字典:
pal = dict(Lunch="seagreen", Dinner="gray")g = sns.FacetGrid(tips, hue="time", palette=pal, size=5)g.map(plt.scatter, "total_bill", "tip", s=50, alpha=.7, linewidth_=.5, edgecolor="white")g.add_legend();
您還可以讓色調的其他方面在色相變數的水平上有所不同,這對於繪製黑白列印時將更易於理解的圖形將有所幫助。 為此,將字典傳遞給hue_kws,其中鍵是繪圖函數關鍵字參數的名稱,值是關鍵字值的列表,每個級別的hue對應一個變數。
g = sns.FacetGrid(tips, hue="sex", palette="Set1", size=5, hue_kws={"marker": ["^", "v"]})g.map(plt.scatter, "total_bill", "tip", s=100, linewidth_=.5, edgecolor="white")g.add_legend();
如果您有多個級別的一個變數,您可以沿著列繪製,但是"wrap"它們,以便跨越多個行。 當這樣做時,將不能使用行(row)變數。
attend = sns.load_dataset("attention").query("subject <= 12")g = sns.FacetGrid(attend, col="subject", col_wrap=4, size=2, ylim=(0, 10))g.map(sns.pointplot, "solutions", "score", color=".3", ci=None);
使用FacetGrid.map()(可以多次調用)繪製圖形之後,您可能需要調整繪圖的某些方面。 FacetGrid對象上還有一些方法可以在更高層次的抽象上操作圖形。 最通用的是FacetGrid.set(),還有其他更專門的方法,如FacetGrid.set_axis_labels(),它遵循內部方面沒有軸標籤的效果。 例如:
with sns.axes_style("white"): g = sns.FacetGrid(tips, row="sex", col="smoker", margin_titles=True, size=2.5)g.map(plt.scatter, "total_bill", "tip", color="#334488", edgecolor="white", lw=.5);g.set_axis_labels("Total bill (US Dollars)", "Tip");g.set(xticks=[10, 30, 50], yticks=[2, 6, 10]);g.fig.subplots_adjust(wspace=.02, hspace=.02);
對於更多的定製,您可以直接使用underling matplotlib圖形和Axes對象,它們分別作為圖和軸(二維數組)的成員屬性存儲。 當沒有行或列面的圖形時,還可以使用ax屬性直接訪問單個軸。
g = sns.FacetGrid(tips, col="smoker", margin_titles=True, size=4)g.map(plt.scatter, "total_bill", "tip", color="#338844", edgecolor="white", s=50, lw=1)for ax in g.axes.flat: ax.plot((0, 50), (0, .2 * 50), c=".2", ls="--")g.set(xlim=(0, 60), ylim=(0, 14));
將自定義函數應用在網格上
在使用FacetGrid時,並不限於現有的matplotlib和Seaborn功能。但是,要正常工作,使用必須遵循以下規則:
- 必須繪製在「當前活動」的matplotlib軸上。 這對matplotlib.pyplot命名空間中的函數是正確的,如果要使用其方法,可以調用plt.gca來獲取對當前Axes的直接引用。
- 它必須接受它在位置參數中繪製的數據。 在內部,FacetGrid將傳遞一系列針對傳遞給FacetGrid.map()的命名位置參數的數據。
- 它必須能夠接受color和label關鍵字參數,理想情況下它將非常有用。在大多數情況下,使用一個通用的**kwargs字典是最簡單的,並將其傳遞給底層的繪圖函數。
我們來看一下您可以繪製的功能的最簡單的例子。該函數只需要給出每個方向的向量的數據:
def quantile_plot(x, **kwargs): qntls, xr = stats.probplot(x, fit=False) plt.scatter(xr, qntls, **kwargs)g = sns.FacetGrid(tips, col="sex", size=4)g.map(quantile_plot, "total_bill");
如果我們想做一個雙變數圖,你應該編寫函數,以便它接受x軸為第一個變數和y軸為第二個變數:
def qqplot(x, y, **kwargs): _, xr = stats.probplot(x, fit=False) _, yr = stats.probplot(y, fit=False) plt.scatter(xr, yr, **kwargs)g = sns.FacetGrid(tips, col="smoker", size=4)g.map(qqplot, "total_bill", "tip");
因為plt.scatter接受color和label關鍵字參數並正確運行,我們可以簡單的再添加一個hue參數:
g = sns.FacetGrid(tips, hue="time", col="sex", size=4)g.map(qqplot, "total_bill", "tip")g.add_legend();
這種方法還允許我們使用額外的sns設置來區分hue變數的級別,依賴這些關鍵字的參數將使得顯示擺脫對刻面變數的依賴:
g = sns.FacetGrid(tips, hue="time", col="sex", size=4, hue_kws={"marker": ["s", "D"]})g.map(qqplot, "total_bill", "tip", s=40, edgecolor="w")g.add_legend();
一些時候,將需要映射一個適合的color和label關鍵字參數以達到預期的效果。在這種情況下,您將會有明確地把握並熟悉處理自定義函數的邏輯。例如這種方法將允許使用映射plt.hexbin函數和那些類似的不方便使用FacetGrid API的調用:
def hexbin(x, y, color, **kwargs): cmap = sns.light_palette(color, as_cmap=True) plt.hexbin(x, y, gridsize=15, cmap=cmap, **kwargs)with sns.axes_style("dark"): g = sns.FacetGrid(tips, hue="time", col="time", size=4)g.map(hexbin, "total_bill", "tip", extent=[0, 50, 0, 10]);
用PairGrid and pairplot()繪製成對的關係
PairGrid還允許您使用相同的繪圖類型快速繪製小子圖的網格,以在每個圖形中顯示數據。在一個PairGrid中,每個行和列分配給一個不同的變數,所以生成的圖顯示了數據集中的每個成對關係。這種風格的繪圖有時被稱為「散點圖矩陣」,因為這是顯示每個關係的最常見方式,但是PairGrid不僅限於散點圖。
了解FacetGrid和PairGrid之間的區別很重要。在前者中,每個方面顯示出與其他變數的不同級別相同的關係。在後者中,每個圖都顯示不同的關係(儘管上下三角形將具有鏡像圖)。使用PairGrid可以為您提供非常快速,非常高級的匯總數據集中有趣的關係。
該類的基本用法與FacetGrid非常相似。首先初始化網格,然後將繪圖函數傳遞給map方法,並在每個子圖上調用它。還有一個配套功能,pairplot()交易了一些靈活性更快的繪圖。
iris = sns.load_dataset("iris")g = sns.PairGrid(iris)g.map(plt.scatter);
可以在對角線上繪製不同的函數,以顯示每列中變數的單變數分布。 請注意,軸刻度線將不對應於該圖的計數或密度軸。
g = sns.PairGrid(iris)g.map_diag(plt.hist)g.map_offdiag(plt.scatter);
使用該圖的非常常見的方法是通過單獨的分類變數來繪製觀察值。 例如,虹膜數據集對於三種不同種類的鳶尾花中的每一種進行四次測量,以便您可以看到它們如何不同。
g = sns.PairGrid(iris, hue="species")g.map_diag(plt.hist)g.map_offdiag(plt.scatter)g.add_legend();
默認情況下,使用數據集中的每個數字列,但如果需要,您可以專註於特定的關係。
g = sns.PairGrid(iris, vars=["sepal_length", "sepal_width"], hue="species")g.map(plt.scatter);
也可以在上下三角形中使用不同的功能來強調關係的不同方面。
g = sns.PairGrid(iris)g.map_upper(plt.scatter)g.map_lower(sns.kdeplot, cmap="Blues_d")g.map_diag(sns.kdeplot, lw=3, legend=False);
具有對角線上的身份關係的方形網格實際上只是一個特殊情況,您可以在行和列中繪製不同的變數。
g = sns.PairGrid(tips, y_vars=["tip"], x_vars=["total_bill", "size"], size=4)g.map(sns.regplot, color=".3")g.set(ylim=(-1, 11), yticks=[0, 5, 10]);
當然,sns屬性是可配置的。 例如,您可以使用不同的調色板(例如,顯示色調變數的順序),並將關鍵字參數傳遞到繪圖函數中。
g = sns.PairGrid(tips, hue="size", palette="GnBu_d")g.map(plt.scatter, s=50, edgecolor="white")g.add_legend();
PairGrid是靈活的,但是要快速查看一個數據集,可以使用pairplot()更容易。 默認情況下,該功能使用散點圖和直方圖,但是還可以添加其他幾種(目前還可以繪製對角線上的對角線和KDEs的回歸圖)。
sns.pairplot(iris, hue="species", size=2.5);
您還可以使用關鍵字參數控制顯示細節,並返回PairGrid實例進行進一步的調整。
g = sns.pairplot(iris, hue="species", palette="Set2", diag_kind="kde", size=2.5)
鬆了口氣,最終全部完成了,沒有爛尾。有時間未禾將對每個章節進行再次的校對和注釋,感謝諸多朋友的支持和鼓勵,閑暇也許還會針對這六章內容出一個快速上手筆記,感謝!
【全文完】
【未禾原創,所有章節已經完結,其他章節請點擊跳轉】
Seaborn(sns)官方文檔學習筆記(第一章 藝術化的圖表控制) - 知乎專欄
Seaborn(sns)官方文檔學習筆記(第二章 斑駁陸離的調色板) - 知乎專欄
Seaborn(sns)官方文檔學習筆記(第三章 分布數據集的可視化) - 知乎專欄
Seaborn(sns)官方文檔學習筆記(第四章 線性關係的可視化) - 知乎專欄
Seaborn(sns)官方文檔學習筆記(第五章 分類數據的繪製) - 知乎專欄
Seaborn(sns)官方文檔學習筆記(第六章 繪製數據網格) - 知乎專欄
推薦閱讀:
※用Pyador進行『異常檢測』: 開發無監督機器學習工具庫(一)
※再也不用擔心網頁編碼的坑了!
※左手用R右手Python系列8——數據去重與缺失值處理
※Scrapy爬蟲框架教程(一)-- Scrapy入門
TAG:Python库 | Python | Matplotlib |