# Seaborn 簡介
> 譯者:[yiran](https://github.com/yiran7324)
Seaborn 是一個基于 [matplotlib](https://matplotlib.org/) 且數據結構與 [pandas](https://pandas.pydata.org/) 統一的統計圖制作庫。
這里列出了一些 seaborn 的功能:
* 計算[多變量](http://seaborn.pydata.org/examples/faceted_lineplot.html#faceted-lineplot)間[關系](http://seaborn.pydata.org/examples/scatter_bubbles.html#scatter-bubbles)的面向數據集接口
* 可視化類別變量的[觀測](http://seaborn.pydata.org/examples/jitter_stripplot.html#jitter-stripplot)與[統計](http://seaborn.pydata.org/examples/pointplot_anova.html#pointplot-anova)
* 可視化[單變量](http://seaborn.pydata.org/examples/distplot_options.html#distplot-options)或[多變量](http://seaborn.pydata.org/examples/joint_kde.html#joint-kde)分布并與其子數據集[比較](http://seaborn.pydata.org/examples/horizontal_boxplot.html#horizontal-boxplot)
* 控制[線性回歸](http://seaborn.pydata.org/examples/anscombes_quartet.html#anscombes-quartet)的不同[因變量](http://seaborn.pydata.org/examples/logistic_regression.html#logistic-regression)并進行參數估計與作圖
* 對復雜數據進行易行的整體[結構](http://seaborn.pydata.org/examples/scatterplot_matrix.html#scatterplot-matrix)可視化
* 對[多表統計圖](http://seaborn.pydata.org/examples/faceted_histogram.html#faceted-histogram)的制作高度抽象并簡化可視化過程
* 提供多個內建[主題](http://seaborn.pydata.org/tutorial/aesthetics.html#aesthetics-tutorial)渲染 matplotlib 的圖像樣式
* 提供[調色板](http://seaborn.pydata.org/tutorial/color_palettes.html#palette-tutorial)工具生動再現數據
Seaborn 框架旨在以數據可視化為中心來挖掘與理解數據。它提供的面向數據集制圖函數主要是對行列索引和數組的操作,包含對整個數據集進行內部的語義映射與統計整合,以此生成富于信息的圖表。
下面是一些 ?? 的喵:
```py
import seaborn as sns
sns.set()
tips = sns.load_dataset("tips")
sns.relplot(x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
data=tips);
```

上面發生了什么呢?我們一步步分析:
1. 我們裝載 seaborn,這是這個例子唯一需要的 python 庫。
```py
import seaborn as sns
```
此處,seaborn 實際調用了 matplotlib 作圖。雖然很多任務都可以直接使用 seaborn 提供的函數來完成,不過一些更深層或者更加個性化的可能需要直接使用 matplotlib 來實現,[下面](#intro-plot-customization)會詳細介紹這一點。如果需要獲得交互式體驗,推薦使用 Jupyter/IPython 工具并開啟 [matplotlib 模式](https://ipython.readthedocs.io/en/stable/interactive/plotting.html)。否則,在使用交互式工具時如果想要看到圖片需要調用 matplotlib.pyplot.show 函數。
1. 我們設置并使用 seaborn 默認的主題、尺寸大小以及調色板。
```py
sns.set()
```
這里改變了 [matplotlib rcParam 系統](https://matplotlib.org/users/customizing.html) 所以會影響所有 matplotlib 圖像的顯示,即使你沒有顯式的調用 seaborn 修改這些參數。除了缺省的主題,我們提供一些[其他選項](http://seaborn.pydata.org/tutorial/aesthetics.html#aesthetics-tutorial),你可以獨立的控制圖片風格與尺寸來將他們迅速應用到演講當中(例如,在演講投影中使用一個擁有可閱讀字體的圖表)。如果你傾向于使用默認 matplotlib 主題或者其他的內置樣式,你可以跳過這一部分,只使用 seaborn 提供的制圖函數。
1. 裝載數據集
```py
tips = sns.load_dataset("tips")
```
文檔中的代碼多數會使用 [`load_dataset()`](generated/seaborn.load_dataset.html#seaborn.load_dataset "seaborn.load_dataset") 去取得樣例數據集。這些數據集沒什么特殊,都是 pandas 的數據結構(dataframes),所以我們也可以使用 `pandas.read_csv` 或者手動輸入創建數據集。在文檔中,多數作圖都使用 `tips` 數據集,非常無聊但是就說明狀況的作用還是可以。`tips` 數據集提供了一種“整潔”的整合數據的方式,所以如果你使用這種方式來整合自己的數據,使用 seaborn 再好不過了。[下面](#intro-tidy-data)詳細解釋為什么。
1. 我們寫一個多子圖散點圖,分配語義變量
```py
sns.relplot(x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
data=tips)
```
這張圖說明了 `tips` 數據集中五個變量的關系,三個是數值變量,另外兩個是類別變量。其中 `total_bill` 和 `tip` 這兩個數值變量決定了軸上每個點出現的位置,另外一個 `size` 變量影響著出現點的大小。第一個類別變量 `time` 將散點圖分為兩個子圖,第二個類別變量 `smoker` 決定點的形狀。
所有上述內容均由 [`relplot`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 一次調用生成。注意,在函數調用過程中,我們僅僅使用變量名來劃分圖像中的不同的語義。如果直接使用 matplotlib ,就必須將變量轉換為可視化函數的參數(例如,指定顏色,指定每個類別的制圖方式),這在 seaborn 中被自動執行了,以此讓使用者將注意力放在他們要解決的問題上。
## 接口抽象
因為不存在可視化數據的最好方式,每一個制圖所描述的問題都有自己最合適的可視化方法。seaborn 旨在讓可視化方法間的切換變得更容易,有時僅僅需要改變同一個接口中的參數即可。
函數 [`relplot()`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 之所以這樣命名是因為設計這個函數的初衷是想讓他體現多個統計間的關系。散點圖可以很好的體現統計數據間的關系,但是如果有一個變量具有時間意義,那線狀圖可能更好一點,因此,[`relplot()`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 函數提供了一個 `kind` 接口可以很方便的用作于改變圖像的組織方式。
```py
dots = sns.load_dataset("dots")
sns.relplot(x="time", y="firing_rate", col="align",
hue="choice", size="coherence", style="choice",
facet_kws=dict(sharex=False),
kind="line", legend="full", data=dots);
```

參數 `size` 和 `style` 被散點圖和線狀圖共享,但是他們對這些可視化結果產生的影響是不同的(例如,改變點大小和線的樣式)。這些細節在實際使用中是無需被關注的,我們只需要將注意力放在組織圖像的結構與我們想表達的信息中。
## 估計與誤差
我們常常會想知道一個變量的均值函數以便在計算其他變量時作為可用參數。seaborn 的許多函數都可以自動的計算參數估計,這在解決一些問題中是十分必要的。
```py
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", col="region",
hue="event", style="event",
kind="line", data=fmri);
```

估計統計參數時,seaborn 使用了 bootstrap 方法計算置信區間和誤差以表示估計的不確定性程度。
Seaborn 還能實現一些不是很好用語言描述統計估計。比如,使用 [`lmplot()`](generated/seaborn.lmplot.html#seaborn.lmplot "seaborn.lmplot") 可以將一個線性回歸模型放在散點圖當中去:
```py
sns.lmplot(x="total_bill", y="tip", col="time", hue="smoker",
data=tips);
```

## 分類圖
標準的散點圖和線狀圖用來可視化數值型數據,但是可能有些變量含有分類信息,之前的做法不再合適。我們提供了一些可視化分類變量的函數,在 [`catplot()`](generated/seaborn.catplot.html#seaborn.catplot "seaborn.catplot") 中可以找到。和 [`relplot()`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 相似的地方是,寫 [`catplot()`](generated/seaborn.catplot.html#seaborn.catplot "seaborn.catplot") 函數的目的是為了提供一個面向數據集的通用接口,不僅可以顯示數值變量,同時展示一個或多個類別變量。
在下面這種圖中,你可以改變觀測的粒聚集度,最好的情況是,所有的觀測值都被調整的恰好到不會重疊但是又是沿著類別軸的:
```py
sns.catplot(x="day", y="total_bill", hue="smoker",
kind="swarm", data=tips);
```

你也可以使用核密度估計來表示這些觀測可能來源于的樣本:
```py
sns.catplot(x="day", y="total_bill", hue="smoker",
kind="violin", split=True, data=tips);
```

或者你可以在每個嵌套類別變量中求其唯一均值與置信區間:
```py
sns.catplot(x="day", y="total_bill", hue="smoker",
kind="bar", data=tips);
```

## 圖與軸的函數
了解 seaborn 提供的不同函數間的區別非常重要,到目前為止我們見到的函數都是基于 figure-level 的函數。由于直接創建包含子圖的 matplotlib 圖像,數據得以被沿著軸展開,挖掘數據得到了優化。這些函數還可以做一些比較有技巧性的事情,比如把圖例放在軸外。我們可以使用 [`FacetGrid`](generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid") 來完成這些事情。
每一個 figure-level 的圖像 `kind` (指傳給 kind 參數位置的圖類別變量)都包含著一個特殊的 axes-level 作為 [`FacetGrid`](generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid") 的對象。例如,散點圖實際上使用的是 [`scatterplot()`](generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot") 函數,條形圖使用的是 [`barplot()`](generated/seaborn.barplot.html#seaborn.barplot "seaborn.barplot") 函數,這些函數被稱為 axes-level 因為他們只會作用一個獨立 matplotlib 圖像軸不會影響到其他剩余軸上的子圖。
總之就是 figure-level 函數控制整個圖像,axes-level 的函數可以和 matplotlib 圖進行更復雜的結合,無論其他軸上的子圖是否由 seaborn 作出。
```py
import matplotlib.pyplot as plt
f, axes = plt.subplots(1, 2, sharey=True, figsize=(6, 4))
sns.boxplot(x="day", y="tip", data=tips, ax=axes[0])
sns.scatterplot(x="total_bill", y="tip", hue="day", data=tips, ax=axes[1]);
```

使用 figure-level 函數控制圖像大小的方法和控制 matplotlib 圖的方法有一點不同。figure-level 函數不會設置整個圖的大小,而是調整每個組成圖的子圖的大小,并且對于子圖設定高度與比例,不會去分別設定高度和寬度。這樣的參數化形式使得控制圖表大小更容易了,并不需要非得仔細計算到底結果圖會包含多少行、多少列,即使這樣容易讓人比較暈:
```py
sns.relplot(x="time", y="firing_rate", col="align",
hue="choice", size="coherence", style="choice",
height=4.5, aspect=2 / 3,
facet_kws=dict(sharex=False),
kind="line", legend="full", data=dots);
```

區別 figure-level 函數和 axes-level 函數的方法就是去看函數是否攜帶一個 `ax=` 參數。或者你可以查看他們的輸出類型:axes-level 函數返回一個 matplotlib `axes`,figure-level 函數返回一個 [`FacetGrid`](generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid")。
## 數據集結構可視化
在 seaborn 中創建多子圖的可視化結果有兩種方法,兩種方法都可以刻畫數據集的結構。第一種
[`jointplot()`](generated/seaborn.jointplot.html#seaborn.jointplot "seaborn.jointplot") 方法注重單對單關系:
```py
iris = sns.load_dataset("iris")
sns.jointplot(x="sepal_length", y="petal_length", data=iris);
```

另一種是 [`pairplot()`](generated/seaborn.pairplot.html#seaborn.pairplot "seaborn.pairplot") ,提供對數據更為全面的可視化。對于每對數據間的關系以及邊緣分布都有考察,你可以選擇用哪里分類變量作為條件:
```py
sns.pairplot(data=iris, hue="species");
```

這兩種方法在數據可視化都提供一些自定義選項,他們都是對于兩個高度可自定義的多圖作圖函數 [`JointGrid`](generated/seaborn.JointGrid.html#seaborn.JointGrid "seaborn.JointGrid") 和 [`PairGrid`](generated/seaborn.PairGrid.html#seaborn.PairGrid "seaborn.PairGrid") 再封裝。
## 自定義樣式
Seaborn 庫選擇盡可能美觀的設計,并且添加富于信息的標簽。如果需要設計更為精致的圖片可能會需要多執行一些步驟,這有多種方法。
第一種方法是使用 seaborn 給你的其他的主題。設置了不同的主題或者調色板樣式會讓整個圖的效果都不一樣:
```py
sns.set(style="ticks", palette="muted")
sns.relplot(x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
data=tips);
```

如果要僅針對圖像設計,所有的 seaborn 函數都接受一系列的可選參數來改變默認的語義映射,比如顏色。(對顏色的恰當選擇在數據可視化中非常關鍵,seaborn 提供了[附加支持]http://seaborn.pydata.org/tutorial/color_palettes.html#palette-tutorial) 來引導調色板的使用)。
最后,當 seaborn 的函數與 matploblib 函數具有顯然一致性時(例如 [`scatterplot()`](generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot") 和 `plt.scatter`),多余的參數會被直接傳給 matploblib 層:
```py
sns.relplot(x="total_bill", y="tip", col="time",
hue="size", style="smoker", size="size",
palette="YlGnBu", markers=["D", "o"], sizes=(10, 125),
edgecolor=".2", linewidth=.5, alpha=.75,
data=tips);
```

注意 [`relplot()`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 或者其他 figure-level 函數,因為當 [`relplot()`](generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot") 函數傳遞一些額外的關鍵字參數到 seaborn 底層的 axes-level 函數時,相當于將這些參數直接傳給了底層 matplotlib 函數,這會使得你尋找對應文檔變得有些麻煩,不過原則上是可以做到很高的自定義程度的。
有些 figure-level 的函數自定義可以通過傳遞額外參數到 [`FacetGrid`](generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid") 來實現,你可以使用這個對象的方法來控制圖像的屬性。甚至可以修改需要被作圖的 matploblib 對象的值達到效果:
```py
g = sns.catplot(x="total_bill", y="day", hue="time",
height=3.5, aspect=1.5,
kind="box", legend=False, data=tips);
g.add_legend(title="Meal")
g.set_axis_labels("Total bill ($)", "")
g.set(xlim=(0, 60), yticklabels=["Thursday", "Friday", "Saturday", "Sunday"])
g.despine(trim=True)
g.fig.set_size_inches(6.5, 3.5)
g.ax.set_xticks([5, 15, 25, 35, 45, 55], minor=True);
plt.setp(g.ax.get_yticklabels(), rotation=30);
```

Figure-level 函數作用于需要高效顯示數據的情況,所以如果要更精確的調整大小與組織形式,直接使用 matploblib 或者使用對應的 seaborn axes-level 函數。matploblib 具有易于理解和強大的接口,任何有關圖像屬性的值都可以通過接口來完成設置。最好是將高度抽象的 seaborn 接口和可深度自定義的 matplotlib 接口一起使用來制作達到[出版質量](https://github.com/wagnerlabpapers/Waskom_PNAS_2017)的最終成果。
## 組織數據集
之前提到過,如果你的數據整合的比較好,seaborn 的表現也會很出眾。這種能稱為做“長型”或者“整潔”數據在[這里](http://vita.had.co.nz/papers/tidy-data.html)被詳細解釋。這些方式可以大致概括為:
1. 每個變量占有一個列
2. 每個觀測占有一個行
你的數據是否整潔了?一種比較好的思考方式是去想你要怎么畫你的圖,從這一點來講,變量就是圖中一種具有規律展現形式的元素。如果看看樣例 `tips` 會比較好:
```py
tips.head()
```
| | total_bill | tip | sex | smoker | day | time | size |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
| --- | --- | --- | --- | --- | --- | --- | --- |
從某種意義上講,使用這種組織方式開始可能會感覺尷尬,比如使用時間序列數據,將時間點作為觀測值放在列中。我們[之前](#intro-stat-estimation)使用的 `fmri` 數據集展示了一個整潔的時間點在不同行間的組織形式:
```py
fmri.head()
```
| | subject | timepoint | event | region | signal |
| --- | --- | --- | --- | --- | --- |
| 0 | s13 | 18 | stim | parietal | -0.017552 |
| --- | --- | --- | --- | --- | --- |
| 1 | s5 | 14 | stim | parietal | -0.080883 |
| --- | --- | --- | --- | --- | --- |
| 2 | s12 | 18 | stim | parietal | -0.081033 |
| --- | --- | --- | --- | --- | --- |
| 3 | s11 | 18 | stim | parietal | -0.046134 |
| --- | --- | --- | --- | --- | --- |
| 4 | s10 | 18 | stim | parietal | -0.037970 |
| --- | --- | --- | --- | --- | --- |
許多 seaborn 函數都提供了畫出大范圍數據圖的功能,雖然在函數性上有所限制。要利用好整合較好的數據集,你肯定會使用 `pandas.melt` 函數來解構一個大的數據集。參考[這篇](https://tomaugspurger.github.io/modern-5-tidy.html) pandas 開發者寫的博客。
## 下一步
繼續往下看,你有多個選擇。比如你可能想去[安裝 seaborn](installing.html#installing)。然后你可以看看[制圖樣例](http://seaborn.pydata.org/examples/index.html#example-gallery)來了解 seaborn 到底可以繪制什么樣的圖。或者你可以閱讀[官方教程](tutorial.html#tutorial)來深入了解你所需要的工具。你也可以查看附帶樣例的[接口參考](api.html#api-ref)來實現你不同的想法。
- seaborn 0.9 中文文檔
- Seaborn 簡介
- 安裝和入門
- 可視化統計關系
- 可視化分類數據
- 可視化數據集的分布
- 線性關系可視化
- 構建結構化多圖網格
- 控制圖像的美學樣式
- 選擇調色板
- seaborn.relplot
- seaborn.scatterplot
- seaborn.lineplot
- seaborn.catplot
- seaborn.stripplot
- seaborn.swarmplot
- seaborn.boxplot
- seaborn.violinplot
- seaborn.boxenplot
- seaborn.pointplot
- seaborn.barplot
- seaborn.countplot
- seaborn.jointplot
- seaborn.pairplot
- seaborn.distplot
- seaborn.kdeplot
- seaborn.rugplot
- seaborn.lmplot
- seaborn.regplot
- seaborn.residplot
- seaborn.heatmap
- seaborn.clustermap
- seaborn.FacetGrid
- seaborn.FacetGrid.map
- seaborn.FacetGrid.map_dataframe
- seaborn.PairGrid
- seaborn.PairGrid.map
- seaborn.PairGrid.map_diag
- seaborn.PairGrid.map_offdiag
- seaborn.PairGrid.map_lower
- seaborn.PairGrid.map_upper
- seaborn.JointGrid
- seaborn.JointGrid.plot
- seaborn.JointGrid.plot_joint
- seaborn.JointGrid.plot_marginals
- seaborn.set
- seaborn.axes_style
- seaborn.set_style
- seaborn.plotting_context
- seaborn.set_context
- seaborn.set_color_codes
- seaborn.reset_defaults
- seaborn.reset_orig
- seaborn.set_palette
- seaborn.color_palette
- seaborn.husl_palette
- seaborn.hls_palette
- seaborn.cubehelix_palette
- seaborn.dark_palette
- seaborn.light_palette
- seaborn.diverging_palette
- seaborn.blend_palette
- seaborn.xkcd_palette
- seaborn.crayon_palette
- seaborn.mpl_palette
- seaborn.choose_colorbrewer_palette
- seaborn.choose_cubehelix_palette
- seaborn.choose_light_palette
- seaborn.choose_dark_palette
- seaborn.choose_diverging_palette
- seaborn.load_dataset
- seaborn.despine
- seaborn.desaturate
- seaborn.saturate
- seaborn.set_hls_values