# 可視化統計關系
> 譯者:[JNJYan](https://github.com/JNJYan)
統計分析是了解數據集中的變量如何相互關聯以及這些關系如何依賴于其他變量的過程。可視化是此過程的核心組件,這是因為當數據被恰當地可視化時,人的視覺系統可以看到指示關系的趨勢和模式。
我們將在本教程中討論三個 seaborn 函數。我們最常用的是[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")。這是一個[figure-level](../introduction.html#intro-func-types)的函數,可以用散點圖和線圖兩種通用的方法來可視化統計關系。[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")將[`FacetGrid`](../generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid") 與兩個[axes-level]()函數組合在一起:
* [`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot") (`kind="scatter"`; 默認值)
* [`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")(`kind="line"`)
正如我們將要看到的,這些函數可能非常有啟發性,因為他們使用簡單且易于理解的數據表示形式,且仍然能夠表示復雜的數據集結構。之所以可以這樣,是因為它們可以通過色調、大小和樣式的語義映射最多三個額外的變量來增強繪制的二維圖形。
```py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")
```
## 用散點圖關聯變量
散點圖是數據可視化的支柱,它通過點云描繪了兩個變量的聯合分布,其中每個點代表數據集中的一個觀測值。這種描述能夠使我們通過視覺推斷出許多信息,他們之間是否存在任何有意義的關系。
在 seaborn 中有多種方式繪制散點圖。當兩個變量的是數值型時,最基本的是函數[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")。在 [類別可視化](categorical.html#categorical-tutorial),我們將會看到使用散點圖來顯示類別數據的專用工具。[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")是[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")中`kind`的默認類型(也可以通過`kind="scatter"`來設置):
```py
tips = sns.load_dataset("tips")
sns.relplot(x="total_bill", y="tip", data=tips);
```

雖然這些點是以二維繪制的,但可以通過根據第三個變量對點進行著色來將另一個維度添加到繪圖中。在 seaborn 中,這被稱為使用“色調語義”,因為該點的顏色獲得了意義:
```py
sns.relplot(x="total_bill", y="tip", hue="smoker", data=tips);
```

為了強調類別之間的差異并提高可訪問性,可以為每個類別使用不同的標記樣式:
```py
sns.relplot(x="total_bill", y="tip", hue="smoker", style="smoker",
data=tips);
```

也可以通過單獨改變每個點的色調和樣式來表示四個變量。但是這應該謹慎,因為眼睛對形狀的敏感度遠低于對顏色的敏感度:
```py
sns.relplot(x="total_bill", y="tip", hue="smoker", style="time", data=tips);
```

在上面的例子中,色調語義表示類別,所以使用了默認的[定性調色板](color_palettes.html#palette-tutorial)。如果色調語義表示數值(特別是,如果它可以轉換為浮點數),默認的顏色切換到順序調色板:
```py
sns.relplot(x="total_bill", y="tip", hue="size", data=tips);
```

在這兩種情況下,您都可以自定義調色板,有多種方式可以實現。在這里,我們使用[`cubehelix_palette()`](../generated/seaborn.cubehelix_palette.html#seaborn.cubehelix_palette "seaborn.cubehelix_palette")的字符串接口自定義一個順序調色板:
```py
sns.relplot(x="total_bill", y="tip", hue="size", palette="ch:r=-.5,l=.75", data=tips);
```

第三個語義變量改變每個點的大小:
```py
sns.relplot(x="total_bill", y="tip", size="size", data=tips);
```

與[`matplotlib.pyplot.scatter()`](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter "(in Matplotlib v2.2.2)")不同,變量的值不用于直接決定點的面積。數據單位中的值范圍被規范化為面積單位的范圍,這個范圍可以自定義:
```py
sns.relplot(x="total_bill", y="tip", size="size", sizes=(15, 200), data=tips);
```

在[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")API 示例中展示了更多如何通過自定義使用不同語義來顯示統計關系的示例。
## 強調線圖的連續性
散點圖是非常有效的,但是沒有通用的最優可視化類型。相反,可視表示應該適應數據集的細節以及您試圖用圖表回答的問題。
對于某些數據集,您可能希望了解一個變量中的變化關于時間的函數,或者類似的連續變量。在這種情況下,一個很好的選擇是繪制線圖。
在 seaborn 中,這可以通過[`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")函數直接實現,也可以通過設置[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")的參數`kind="line"`來實現:
```py
df = pd.DataFrame(dict(time=np.arange(500),
value=np.random.randn(500).cumsum()))
g = sns.relplot(x="time", y="value", kind="line", data=df)
g.fig.autofmt_xdate()
```

由于[`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")假設您想要將`y`繪制為`x`的函數,默認行為是在繪制之前按數字`x`對數據進行排序。但是,這可以被禁用:
```py
df = pd.DataFrame(np.random.randn(500, 2).cumsum(axis=0), columns=["x", "y"])
sns.relplot(x="x", y="y", sort=False, kind="line", data=df);
```

### 聚合和表示不確定性
更復雜的數據集將對`x`變量的相同值有多個觀測值。seaborn 的默認行為是通過繪制平均值及 95%的置信區間,在每個`x`周圍聚合多個測量值:
```py
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind="line", data=fmri);
```

置信區間是使用 bootstrapping 計算的,對于較大的數據集,它可能是時間密集型的。因此,可以禁用它們:
```py
sns.relplot(x="timepoint", y="signal", ci=None, kind="line", data=fmri);
```

尤其是對于較大的數據,另一個不錯的選擇是通過繪制標準差,而不是置信區間來表示分布在每個時間點的分布范圍:
```py
sns.relplot(x="timepoint", y="signal", kind="line", ci="sd", data=fmri);
```

可以通過設置`estimator`參數為`None`,來完全停用聚合。當數據在每個點上有多個觀察值時,這可能會產生奇怪的效果。
```py
sns.relplot(x="timepoint", y="signal", estimator=None, kind="line", data=fmri);
```

### Plotting subsets of data with semantic mappings
函數[`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")與[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")具有相同的靈活性:它可以通過修改繪圖元素的色調,大小和樣式來顯示最多三個附加變量。它使用于[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")相同的 API,這意味著我們不需要停下來考慮控制 matplotlib 中線條與點外觀的參數。
在[`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")中使用語義也將決定數據的聚合方式。例如,添加具有兩個級別的色調語義將繪圖分成兩行以及錯誤帶,每個都著色以指示它們對應于哪個數據集。
```py
sns.relplot(x="timepoint", y="signal", hue="event", kind="line", data=fmri);
```

在線條圖中添加樣式語義默認情況下會改變線條中的破折號模式:
```py
sns.relplot(x="timepoint", y="signal", hue="region", style="event",
kind="line", data=fmri);
```

但您可以通過每次觀察時使用的標記識別子集,或者使用短劃線或代替它們:
```py
sns.relplot(x="timepoint", y="signal", hue="region", style="event",
dashes=False, markers=True, kind="line", data=fmri);
```

與散點圖一樣,要謹慎使用多個語義制作線圖。雖然有時提供信息,但它們也很難解析和解釋。但當您只檢查一個附加變量的變化時,更改線條的顏色和樣式也很有用。當打印成黑白或有色盲的人觀看時,這可以使繪圖更容易訪問:
```py
sns.relplot(x="timepoint", y="signal", hue="event", style="event",
kind="line", data=fmri);
```

當您使用重復測量數據(即,您有多次采樣的單位)時,您還可以單獨繪制每個采樣單位,而無需通過語義區分它們。這樣可以避免使圖例混亂:
```py
sns.relplot(x="timepoint", y="signal", hue="region",
units="subject", estimator=None,
kind="line", data=fmri.query("event == 'stim'"));
```

[`lineplot()`](../generated/seaborn.lineplot.html#seaborn.lineplot "seaborn.lineplot")中默認的色彩映射和圖例的處理還取決于色調語義是類別還是數值:
```py
dots = sns.load_dataset("dots").query("align == 'dots'")
sns.relplot(x="time", y="firing_rate",
hue="coherence", style="choice",
kind="line", data=dots);
```

可能會發生這樣的情況:即使`hue`變量是數值,它也很難用線性色標表示。如下示例,其中`hue`變量的級別以對數方式縮放。您可以通過傳遞列表或字典為每一行提供特定的顏色值:
```py
palette = sns.cubehelix_palette(light=.8, n_colors=6)
sns.relplot(x="time", y="firing_rate",
hue="coherence", style="choice",
palette=palette,
kind="line", data=dots);
```

或者您可以更改色彩映射的規范化方式:
```py
from matplotlib.colors import LogNorm
palette = sns.cubehelix_palette(light=.7, n_colors=6)
sns.relplot(x="time", y="firing_rate",
hue="coherence", style="choice",
hue_norm=LogNorm(),
kind="line", data=dots);
```

第三個語義,`size`改變線的寬度:
```py
sns.relplot(x="time", y="firing_rate",
size="coherence", style="choice",
kind="line", data=dots);
```

雖然`size`變量通常是數值型的,但是也可以用線寬映射為類別變量。在這樣做的時候要小心,因為除了“粗”線和“細”線之外,很難區分更多。然而,當線具有高頻變異性時,破折號很難被察覺,因此在這種情況下,使用不同的寬度可能更有效:
```py
sns.relplot(x="time", y="firing_rate",
hue="coherence", size="choice",
palette=palette,
kind="line", data=dots);
```

### 用日期數據繪圖
線圖通常用于可視化與實際日期和時間相關的數據。這些函數以原始格式將數據傳遞給底層的 matplotlib 函數,因此他們可以利用 matplotlib 在 tick 標簽中設置日期格式的功能。但是所有這些格式化都必須在 matplotlib 層進行,您應該參考 matplotlib 文檔來了解它是如何工作的:
```py
df = pd.DataFrame(dict(time=pd.date_range("2017-1-1", periods=500),
value=np.random.randn(500).cumsum()))
g = sns.relplot(x="time", y="value", kind="line", data=df)
g.fig.autofmt_xdate()
```

## 顯示與切面的多種關系
我們在本教程中強調,雖然這些函數可以同時顯示幾個語義變量,但這樣做并不總是有效的。但是,當你想要了解兩個變量之間的關系如何依賴于多個其他變量時呢?
最好的方法可能是多次繪制。因為[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")基于[`FacetGrid`](../generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid"),所以這很容易做到。要顯示附加變量的影響,而不是將其分配給圖中的一個語義角色,而是使用它來“切面”可視化。這意味著您可以創建多個軸并在每個軸上繪制數據的子集:
```py
sns.relplot(x="total_bill", y="tip", hue="smoker",
col="time", data=tips);
```

您還可以通過這種方式顯示兩個變量的影響:一個是通過在列上切面而另一個是在行上切面。當您開始向網格添加更多變量時,您可能希望減小圖形大小。請記住,大小[`FacetGrid`](../generated/seaborn.FacetGrid.html#seaborn.FacetGrid "seaborn.FacetGrid")由每個切面的高度和長寬比參數化的:
```py
sns.relplot(x="timepoint", y="signal", hue="subject",
col="region", row="event", height=3,
kind="line", estimator=None, data=fmri);
```

當您想要檢查一個變量的多個級別的效果時,在列上對該變量進行切面處理,然后將切面“包裝”到行中:
```py
sns.relplot(x="timepoint", y="signal", hue="event", style="event",
col="subject", col_wrap=5,
height=3, aspect=.75, linewidth=2.5,
kind="line", data=fmri.query("region == 'frontal'"));
```

這些可視化通常被稱為格點圖,它們非常有效,因為它們以總體模式和與這些模式的偏差的數據格式來呈現數據,便于眼睛觀察。雖然你應該利用[`scatterplot()`](../generated/seaborn.scatterplot.html#seaborn.scatterplot "seaborn.scatterplot")和[`relplot()`](../generated/seaborn.relplot.html#seaborn.relplot "seaborn.relplot")提供的靈活性,但一定要記住,幾個簡單的圖通常比一個復雜的圖更有效。
- 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