seaborn の新バージョン（v0.9.0 (July 2018)）を試してみる

## 概要

[What’s new in each version --v0.9.0 (July 2018)](http://seaborn.pydata.org/whatsnew.html#v0-9-0-july-2018)

seabornがメジャーアップデートをして、バージョン0.9.0がリリースされました。

いくつかの変更点や新たな関数が追加されたようなので、いくつか試してみたいと思います。

特に、散布図の```scatterplot()```や、線グラフの```lineplot()```が良さげなので、それについて詳しく見ます。

コードだけ見たい方は、[以下の文章は飛ばしてこちら](#コード例)からどうぞ。

### 注意！

ベータ版なので、アップデート等は自己責任でお願いします。

## 主な変更点や追加関数

以下、公式ドキュメントの翻訳（意訳）の抜粋。だいぶ粗い訳なので、分かりにくい箇所はドキュメントを参照してください。

---

新しいグラフ関数が追加された。

-  relplot()
-  scatterplot()
-  lineplot()

```relplot()```は ```FacetGrid```と、```scatterplot()```および```lineplot```を組み合わせたそれらのfigure レベルのインターフェースである。 ```relplot()```関数は、seaborn のカテゴリカル変数のグラフ関数の高レベルでデータセット志向なAPIを、より一般的なプロット(散布図や線グラフ)にもたらす。

これらの関数は、色(hue)・大きさ(size)・形(style)を修正することで3つの付加的な変数を表現しながら、2つの連続値変数の関係を可視化することができる。共通の高機能APIが2つの関数に別々に実装されている。例えば、```scatterplot()```におけるサイズは意味的に散布図の点の大きさを縮小拡大させるが、```lineplot()```では線グラフの線の幅を縮小拡大させる。このAPIはデータセット志向なので、いずれの場合も点の大きさや線の幅のための matplotlib のパラメータを直接特定せず、単にデータセットの変数を渡すだけで良い。

既存の seaborn の機能と異なる方法は、色と大きさの表現のために連続値変数を用いる点でより良いサポートを得られる。この機能は将来のバージョンで色の表現を他の関数に広まるかもしれない。（今回のリリースではまだ実装されていない。）

```lineplot()``` 関数は同様に統計的推定をサポートし、既存の tsplot 関数（今のところ存在しているが将来のリリースで削除されうる）を置き換えられつつある。```lineplot()```はライブラリの残りのAPIとより良く協調されていて、大きさと形状を独立に修正することで、追加の変数とより柔軟な関係性を表現できる。同様に時系列データへのサポートも改善している。不確実性を表現する tsplot の難解なオプションは新しい関数では実装されていない。

これらの新しい関数を詳しく説明するたくさんのドキュメントがある。例えば、APIレファレンスにおける様々なオプションの詳細な例や言葉数の多いチュートリアルなどがある。

これらの関数は「ベータ版」状態と考えられるべきである。これらは徹底的にテストされているが、いくつかのエラーは見つけられていないかもしれない。いくつかの要素では修正が計画されている。特に、デフォルトの凡例はこのリリースでは少し雑なままである。最終的には、いくつかのデフォルトの挙動（例えば、デフォルトの点・線の大きさの幅）は将来のリリースで何かしらの変更があるかもしれない。

---

### 感想

今までは散布図も線グラフもjointplotを用いていたけど、データセットを分割して、プロットを重ねていかないと散布図でカテゴリカル変数に従って色分けしたりできなかった。

しかし、今回のアップデートでそういうを簡単にしてくれるようになったらしい。（2018年7月時点では ベータ版らしいが）

Pythonにおけるグラフの描画の柔軟性は、R の```ggplot2```と比べるとやや劣るところがあったけど、こういった改良が加えられていけば、通常レベルの使い勝手ならほとんど遜色なくなっていきそう。


## コード例

seaborn ver0.9.0 の[公式のチュートリアルはこちら](http://seaborn.pydata.org/tutorial/relational.html#relational-tutorial)です。

### セットアップ

```{py:jupyter}
# seaborn を最新版にアップデート
# jupyter notebook 上でシェルコマンドを打つにはコードの最初に ! を付ける。
# 注意！：公式ドキュメントにも書いてありますが、stable beta 版なので各自自己責任でお願いします。
! pip install seaborn -U  # パッケージのアップデートは -U オプションを付ける
```

```{py:python}
import seaborn
print( seaborn.__version__)
# out[]: 0.9.0
```

## scatterplot()

散布図をプロットする。
数値データの x と y の関係を、色・大きさ・形のパラメータを使って表現できる。

```{py:python}
import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
tips.head()
```

| total_bill | tip | sex | smoker | day | time | size |
|:-----------------|:------------------|:------------------|:-----------------|:------------------|:------------------|:-----------------|
| 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
| 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
| 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
| 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
| 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |


### シンプルな散布図

```{py:python}
sns.scatterplot(x="total_bill", y="tip", data=tips)
```

![scp1.png](https://qiita-image-store.s3.amazonaws.com/0/204489/4464726a-bb34-9fab-67ad-53e2853c1d72.png)

### グループごとに色分け

```{py:python}
sns.scatterplot(x="total_bill", y="tip", hue="time", data=tips)
```

![scp2.png](https://qiita-image-store.s3.amazonaws.com/0/204489/2293c51a-4b3f-26db-6d67-fcddd146f9c8.png)

### グループごとに色と形状を同じに分ける

```{py:python}
sns.scatterplot(x="total_bill", y="tip", hue="time", style="time", data=tips)
```

![scp3.png](https://qiita-image-store.s3.amazonaws.com/0/204489/1f050096-044e-ee93-b81c-f9a456cff95a.png)

### グループごとに色と形状を別々に分ける

```{py:python}
sns.scatterplot(x="total_bill", y="tip", hue="day", style="time", data=tips)
```

![scp4.png](https://qiita-image-store.s3.amazonaws.com/0/204489/c12af6a3-e0be-3e04-0283-a3555e04187c.png)

### 点の大きさで 量的変数を表す

```{py:python}
sns.scatterplot(x="total_bill", y="tip", size="size",data=tips)
```

![scp5.png](https://qiita-image-store.s3.amazonaws.com/0/204489/a7f174e1-4b81-2a1e-e368-df136c1f0428.png)

### 点の大きさと色で 量的変数を表す

```{py:python}
sns.scatterplot(x="total_bill", y="tip", hue="size", size="size", data=tips)
```

![scp6.png](https://qiita-image-store.s3.amazonaws.com/0/204489/34819013-954d-04f1-7cc8-c23a7286cae8.png)



## lineplot()

```{py:python}
import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
fmri = sns.load_dataset("fmri")
fmri.head()
```
| subject | timepoint | event | region | signal |
|:-----------------|:------------------|:------------------|:-----------------|:------------------|
| s13 | 18 | stim | parietal | -0.017552 |
| s5 | 14 | stim | parietal | -0.080883 |
| s12 | 18 | stim | parietal | -0.081033 |
| s11 | 18 | stim | parietal | -0.046134 |
| s10 | 18 | stim | parietal | -0.037970 |


### シンプルな線グラフ（信頼区間のエラーバンド付き）

```{py:python}
sns.lineplot(x="timepoint", y="signal", data=fmri)
```

![lnp1.png](https://qiita-image-store.s3.amazonaws.com/0/204489/71143373-56dd-f0ed-372c-0156b22534ed.png)

### グループごとに色分け

```{py:python}
sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri)
```

![lnp2.png](https://qiita-image-store.s3.amazonaws.com/0/204489/98aed823-c6ab-c0e4-d11a-91ee014512d6.png)

### グループごとに色分け・実践/破線分け

```{py:python}
sns.lineplot(x="timepoint", y="signal", hue="event", style="event", data=fmri)
```

![lnp3.png](https://qiita-image-store.s3.amazonaws.com/0/204489/1dcb696d-ac2a-b1a4-450e-83f73f1f60fb.png)

### 色分けと実線/破線分けで、2つの異なる変数を表す

```{py:python}
sns.lineplot(x="timepoint", y="signal", hue="region", style="event", data=fmri)
```

![lnp4.png](https://qiita-image-store.s3.amazonaws.com/0/204489/a4fad18c-758b-e926-eed9-07b2f8e29cd0.png)

### 破線の代わりに点を使ってグループ分け

```{py:python}
sns.lineplot(x="timepoint", y="signal", hue="event", 
             style="event", markers=True, dashes=False, data=fmri)
```

![lnp5.png](https://qiita-image-store.s3.amazonaws.com/0/204489/53ff5f59-0f76-8803-cd1c-e78bb7ba9a8d.png)

### 標準誤差のエラーバー付き線グラフ

```{py:python}
sns.lineplot(x="timepoint", y="signal", hue="event",
             err_style="bars", ci=68, data=fmri)
```

![lnp6.png](https://qiita-image-store.s3.amazonaws.com/0/204489/0982b6a4-5b61-5a63-0f67-3c8c7f9f8768.png)