最新のseabornAPIを全て試してデータ可視化スキルを高める【可視化, 2020/9/9-ver0.11.0】



2020年9月9日にseabornの新バージョンがでましたね
今回はそんなver0.11.0を使いながら可視化の振り返りをしていきます

seaborn公式のギャラリーと関数を参考に全べてのAPIを使ってみたいと思います

可視化だけ興味のある人は真ん中まで飛んでくだし

長いのでctrl + F　で検索かけてください


#検証環境
conda create -n eda python==3.8
conda activate eda

notebook==6.1.4
ipykernel==5.3.4

seaborn==0.11.0
pandas==1.1.2
matplotlib==3.3.2
statsmodels==0.12.0
scipy==1.5.2
scikit-learn==0.23.2
numpy==1.19.2



##前のバージョンとの差分
・distributionの可視化コードの見直し
・カラーマップ調整
・dis,hist,ecdf 関数と機能追加
・kde,rug 関数の見直し(statsmodelsが計算していた部分の削除,平滑化がbw_adjによって調節できる,log_scale変換を処理として選択できる)
・jointplotでhistを選択できるようになった
・縦持ち,横持ちデータの両方に対応
・上記　+　細かい変更

私は新バージョン前まで0.10.1を使っていましたが、set_themeとかもいつの間にか追加されていて設定がだいぶ楽になっていました


##アップデートによって非推奨になった項目

・今後distplotがなくなります、dis,hist関数に早いうちに移行してください




#seabornって何ぞ

##seabornについて簡単におさらい

seabornとはmatplotlibのラッパーで、コードを簡単に、そして綺麗な描画をしてくれるパッケージです
背後にはmatplotが動いていますが、だいぶコードの書き方がシンプルになり複雑な図を一行で表現できたりします
いくつかの関数では前処理に似たフィルターや計算も行ってくれることから、EDA用にも適していると感じます

##seabornの思想

seabornの面白い思想を紹介します


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a9cddccc-9abe-3ead-1c8b-cb8edfd22b4b.png)


seabornはaxes,figureの二つの観点から描画方法を設計しています。
描画する関数のグループ分けは図のようになっており、rel,dis,cat(figure側の関数)によって細かい(axes側の関数による)描画を一括制御することができます。
もちろん個別の関数を呼び出しても使えます。

##細かい関数で描画したほうがスクリプトがわかりやすくない？

一括管理するfigure側の関数では、描画したいキャンバス数を自動的に生成し、グループ分けの処理を行い、描画単位を区切る(facet)ことができます


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b1043962-10e4-d6bb-5b1d-bb2bf97a98d7.png)

また、axes側の関数では(指定しなければ)
・軸の名前なども変更し辛い
・凡例を図中に示してしまう

などの問題があります。
figure側の関数であれば軸や判例を別物として扱い、
set_axis_labelsなどを使うことで一行でラベルや判例の制御を簡単に行うことができます。



#そんなことより可視化だ!!

紹介内容を大きく二分割して、

・最初にオプション(色、軸、凡例、等)
・メジャーなfigure側のrel,dis,catをメインで紹介
・発展的な描画を紹介

に分けていきたいと思います


##【opt-0】オプション的な話

オプション的な話を事前に概要だけでも知ってもらうことで、
以降のplotでの話の入ってきやすさを上げておく

そもそも最新版が入っているのか確認しておきましょう

```python

import pandas as pd
from matplotlib.pyplot as plt
%matplotlib inline

import seaborn as sns
print(sns.__version__)

0.11.0
```


###【opt-1】データを呼び出す

お手軽に有名なデータを使いたい時
[seabornのサポートしているデータはgithub](https://github.com/mwaskom/seaborn-data)上に保存されているので、
使いたいデータを選びload_datasetで呼び出すことができます
呼び出されたデータはpandasのdataframe形式で操作できます


```python
penguins = sns.load_dataset("penguins")
```

###【opt-2】描画テーマを設定

現在のテーマを確認しつつ、使いたいテーマを選ぶ

```python
sns.set_theme

<function seaborn.rcmod.set_theme(context='notebook', style='darkgrid', palette='deep', font='sans-serif', font_scale=1, color_codes=True, rc=None)>
```

styleはグラフ背景の色味を制御します

```
white, dark, whitegrid, darkgrid
```

palletはグラフ図形の色パターンを調整します

```
'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 
'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 
'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r',
 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 
'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 
'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 
'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 
'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 
'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'crest', 'crest_r', 
'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'flare', 'flare_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 
'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 
'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 
'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'icefire', 'icefire_r', 'inferno', 'inferno_r', 'jet',
 'jet_r', 'magma', 'magma_r', 'mako', 'mako_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r',
 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'rocket', 'rocket_r',
 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r',
 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight',
 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r',
 'winter', 'winter_r'
```

```python
sns.set_theme(style="dark",palette='Accent')
df = sns.load_dataset("penguins")
sns.displot(df.flipper_length_mm)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ff87f49b-5f06-a573-92e5-9cfcf2e656d3.png)


###【opt-3】軸ラベルaxisの変更


```python
g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d6ead12a-e581-1edc-4ce8-89e276e0734a.png)


図形に対して外側から上書きすることができます

軸ラベル回転もできる

```python
g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")
g.set_xticklabels(rotation=-45)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/1e3b5e63-2a5f-2176-780a-ab4d16b807b5.png)



ラベルの間隔を20刻みに変える場合は

```python
g.set_xticklabels(step=20)
```

[そのほか使えるメソッド](https://seaborn.pydata.org/generated/seaborn.FacetGrid.html)







###【opt-4】凡例の描画と色分け

色分けは関数内のhueで指定する

axes関数では

```python
df = sns.load_dataset("iris")
sns.scatterplot(data=df,x='sepal_length',y='sepal_width',hue='species')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/cad7ebab-cdd6-1892-8b7a-9c9741e6777d.png)



凡例が自動的に内側に入ってしまうが、
figure側の関数を使えば自動的に外側に出る

```py
df = sns.load_dataset("iris")
sns.relplot(data=df,x='sepal_length',y='sepal_width',hue='species',kind='scatter')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ad550db7-8d87-ed79-e201-b84bb649fe74.png)


###【opt-5】複数描画と凡例

散布図を書きたいが、グループごとに散布図を書きたくなることもある
データに対して複数描画するのはFacetGridで実現できる
どの軸でグループ分けするかはcolによって指定する
(colはcolorでなくcolumn)
グループ分けする軸の質的変数の値から描画エリア数は自動的に決めてくれる

```python
df = sns.load_dataset("penguins")
sns.FacetGrid(df,col='species')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7e7f2381-1726-40b2-1287-9280d4734403.png)

作った描画エリアにマッピング(map)していく

```python
df = sns.load_dataset("penguins")

g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5309e9d7-3f4d-0806-afc2-79cea8a793f0.png)


凡例ほしいという時にはadd_legendによって後付けする

```python
df = sns.load_dataset("penguins")

g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
g.set_axis_labels('flipper_length_mm','bill_depth_mm')
g.add_legend()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c3d273de-9622-2ebf-7345-57c03f6611a1.png)


もう一つ描画の軸を追加したい場合はFacetGridのrowに指定してやれば、さらに分割できる


```python
tips = sns.load_dataset("tips")

g = sns.FacetGrid(tips, col="time",  row="sex")
g.map(sns.scatterplot, "total_bill", "tip")
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/4957ae3f-fc40-b132-bd1f-a8de485aec3c.png)




###【opt-6】全体に対してのタイトルが欲しい

各gridでなく全体にタイトルを付ける時はsuptitleで表示する
matplotが後ろで動いてるのでsuptitleも使える

```python
df = sns.load_dataset("penguins")

g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
g.set_axis_labels('flipper_length_mm','bill_depth_mm')
g.add_legend()

g.fig.suptitle('suptitle',y=1.1,x=0,size=18)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/fc614eb8-d524-fddd-a389-a307de8e36cf.png)




###【opt-7】前処理として変数を対数化してほしい


そのままでは値の幅が広すぎてよくわからない


```python
planets = sns.load_dataset("planets")
sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3e4c16a4-83b5-b28b-af17-5d8e7cf3bb09.png)

scaleを指定することで値の前処理をしてくれる

```python
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/60fab08f-3746-b1e6-c23a-96832704b13f.png)


###【opt-8】軸の棒を消してほしい

背景gridはテーマで消えるけど、X,Y軸の棒は消えない

```python
sns.set_theme(style="white")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/69381e8b-92a2-58d3-bf16-72a011fcc989.png)

despineを使って消す

```python
sns.set_theme(style="white")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
g.despine(left=True, bottom=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2c4c75a4-8393-74e2-629a-e8070e3d9999.png)





###【opt-9】xlimとylimを指定する



```python
sns.set_theme(style="dark",palette='Accent')
df = sns.load_dataset("penguins")
g=sns.displot(df.flipper_length_mm)
g.set(xlim=(0, 300), ylim=(0, 100))
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c0e699fc-3d7a-fbe7-9421-a1e62252398a.png)


もしくはFacetGrid側で設定する

```python
sns.FacetGrid(df,col='species',xlim=[0,10],ylim=[0,10])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9e6470b0-82c3-27cb-a0ba-13260a102d38.png)




##【main-0】メジャーplot紹介


###【main-1】relplotによるscatterとline

####【main-1.1】デフォルトのrel

```python
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r')
g.set(xscale="log", yscale="log")
```

デフォルトで実行した場合scatterになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e9df0063-f0cf-2e93-2bd2-dcb5fb12d886.png)

```python
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r',kind='scatter')
g.set(xscale="log", yscale="log")
```

kindでscatterを指定しても同じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/eebe8c3e-7959-f677-ed81-e07bdee79da5.png)


####【main-1.2】relのkind指定

kindでlineを指定すると点をつないで線形にしてくれる

```python
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r',kind='line')
g.set(xscale="log", yscale="log")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/520dc97b-f83b-a115-b808-77df2b0b16af.png)


####【main-1.3】scatterを値に応じてサイズを変える(bubble plot)

散布図の値をbubble plotのように値によって図形を変化させたい
そんなときはsize引数に値の入っているデータ列を指定する
どの程度の大きさにしたいか上限下限をsizesにlistかtupleで渡す

```python
planets = sns.load_dataset("planets")
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
g = sns.relplot(data=planets,x="distance", y="orbital_period",hue="year", size="mass",palette='nipy_spectral', sizes=(10, 300))
g.set(xscale="log", yscale="log")
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3892c97e-49d7-dcf5-3223-8d7603355dcc.png)

####【main-1.4】図の出力サイズ変更

出力する図の大きさはheightから操作する

```python
planets = sns.load_dataset("planets")
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
g = sns.relplot(data=planets,x="distance", y="orbital_period",hue="year", size="mass",palette='nipy_spectral', sizes=(10, 300),height=10)
g.set(xscale="log", yscale="log")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a8744a06-3bc1-a21c-1820-41c7acbe6e9d.png)


####【main-1.5】lineでの信頼区間

散布図で分かりにくいデータも

```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='scatter')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/590704cf-b503-49f2-fe28-f36b3b465f8e.png)

lineならわかりやすい


```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/0da6a8fa-8621-9c8c-5673-957daad3ce66.png)



信頼区間はciで指定する。
sdか実数を渡すことができ、実数の場合〇%信頼区間を表す
sdは観測地から計算されたsdをそのまま使う

```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line',ci=20)
```

20%信頼区間に指定した

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d97d6b07-e051-755d-4e7c-693eb4d914a3.png)



####【main-1.6】マーカーの指定

イベント点ごとでマーカーを付けたり、信頼区間をエリアでなく棒にすることもできる

```python
sns.relplot(data=fmri, x="timepoint", y="signal", hue="event", err_style="bars", ci=95,markers=True,kind='line')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/82800376-7c38-110f-e29d-ea9e8a2dfc70.png)



####【main-1.7】指定した分析軸で線を増やす

先ほど紹介したscatterの時のサイズのように、styleで分析軸をわけることができる

```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", style="event",kind='line')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2620b775-49ce-27b9-863f-b17686c1b476.png)



もちろんsizeも指定できる

```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", size="event", kind='line')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/14b3e5b3-5d88-ff52-a5c4-1331507a5245.png)




####【main-1.8】指定した分析軸で画面を分ける

描画画面自体を分けたい場合はcolに分けたい軸を指定する


```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", col="event", kind='line')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/872e6343-d44a-6ef9-6d43-7668f44d2735.png)


複数軸での描画の場合、facet_kwsでx軸やy軸のスケールを各図で共有するかどうかを指定できる


```python
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", col="event", kind='line',facet_kws=dict(sharey=False,sharex=False))
```

ラベル消してビックリグラフにならないように注意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9296edcf-d3d0-3883-4198-0ab605a51258.png)



どうしても別の方法で分けたい場合はfigure側の関数でなく、axes側の関数を指定してFacetGridを使うこともできる

```python
fmri = sns.load_dataset("fmri")
g=sns.FacetGrid(fmri,col='event')
g.map_dataframe(sns.lineplot,data=fmri,x='timepoint',y='signal',hue="region")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/4e12b7e7-fa49-6857-871c-44c752e595fc.png)





###【main-2】displotによるhistとkedとecdfとrug




####【main-2.1】displotのデフォルト hist

デフォルトはkind='hist'になっている

```python
penguin = sns.load_dataset("penguins")
sns.displot(data=penguin,x='bill_depth_mm')
#sns.displot(data=penguin,x='bill_depth_mm',kind='hist')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/6fdb6e9f-f1aa-3577-d602-ae03042e8483.png)


elementという引数で表現方法を変化できる
デフォルトはbar


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='poly')
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='step')
```


poly

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d4e7477a-6b90-5ced-313d-82464236e4af.png)



step


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/14016cdf-526c-7ed2-64fe-97b90bfa3d7e.png)



binsで区切る細かさも変えられる


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='poly',bins=100)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2c436d6a-9988-2933-947f-cd3a8c06f9e1.png)





####【main-2.2】histgramにkde(kernel density estimate)を付け加える

```python
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',kde=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2c21a105-958a-0ded-5c25-6b26e4f06e1e.png)



もちろんkind='kde'を指定してあげればhistは消える

```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2e01e2b5-ff87-b32a-b7a7-ccb21cbe61f9.png)


####【main-2.2】histとkdeの元関数でもplotしてみる

```python
sns.histplot(data=penguin,x='bill_depth_mm')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/018e3aca-d168-9876-507a-1ad283cc749e.png)


```python
sns.kdeplot(data=penguin,x='bill_depth_mm')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c966853d-af86-1b46-aef5-97faf3a22cb9.png)



####【main-2.3】kdeの動きを確認する

平滑化の際にどれだけのデータ幅を見て平滑化するかを決めるbw_adjust


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',bw_adjust=.2)
```


0.2のとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/03cd8e35-e33a-a9b4-2dbe-022d547532bf.png)

100のとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/79663499-3337-4668-89be-0623d008e402.png)




####【main-2.4】別の軸で色を変える

いつも通り
hueで色分け
colで画面分け


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a42685e8-9a7c-8857-8fae-0ead00c9c78e.png)





####【main-2.5】積み上げグラフにする

密度関数を積み上げたい場合はstackを指定する
上に乗っかるだけなので、乗っている側のほうが多いと勘違いしないように注意

histでもkdeでも使える


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/fdb59273-6bed-3740-cc13-2f25f29b6175.png)



積み上げ時の境界面を消したいときはlinewidth=0を指定する


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack",linewidth=0)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/bd6a814a-24fc-8dc0-d4d3-d97620ecc880.png)



ほかにもedgecolor="0.1"と指定してあげれば境界線を強めにかいたりできる






積み上げグラフで中の色を抜きたい時にはfillをFalseにする
いよいよ勘違いしそうなグラフになってきた


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="stack",fill=False)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ef7c6d5b-046a-81f7-7b3b-dd79143d4768.png)






####【main-2.6】積み上げない、透かしを入れる、alphaについて


alphaを調整することで色の透けを調節できる


```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',fill=True,alpha=0.5)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3a9e26e5-2102-7aad-f9ef-3cee011c07c7.png)








####【main-2.7】multipleについて、面積比として表現する、かぶせ、横に置く

stackでなくfillを指定することで、全体を1とする面積のなかで、どちらの割合が多いかをplotしてくれるようになる

```python
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="fill")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d948a054-7e18-98d7-fb7d-02376ecf5f31.png)


histで変化を見てみる

```python
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="fill")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="layer")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="dodge")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="stack")
```

fill

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a6bb1062-06fe-5c1d-626f-4f97dfcf75dd.png)

layer

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/05521c16-259f-b340-76e1-992234199bd8.png)

dodge

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d58dde86-9395-a6f1-1eb7-f26b505bb5bc.png)

stack

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2f38b657-f4f8-02e6-657c-71d199fb9420.png)


####【main-2.8】2次元でのplot


histでもkdeでもx,yを指定することで二次元plotにしてくれる
イメージとしては地図の等高線


```python
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm",kind='hist')
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm",kind='kde')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/aefc2a95-14c7-ef23-af9b-740e74173665.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a9f4f8d7-3bab-56b8-9df0-d02c06a2d75e.png)


色分けはhue
塗りつぶしはfill
画面分けはcol
という規則に変わりはない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e5d92679-16c9-385c-0e7d-829fb1da8e6c.png)



####【main-2.9】2次元での色グラデーション

色のグラデーションを付けたければパターンをcmapに指定して

値の入っていない(確率の低い)ところも塗りつぶすthresh = 0 (1より小さい正の値)
グラデーションの段階の細かさを指定levelsで調整


```python
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm", kind="kde",fill=True, thresh=0, levels=10, cmap='cubehelix')
```


 thresh=0, levels=10

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c7b59e2e-aa54-3aad-b76a-5777bc429c5d.png)

 thresh=0.8, levels=10

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/69a9d723-1635-2a97-6bfc-a94b4af55dc8.png)


 thresh=0, levels=100

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/469384b5-73ad-0028-d913-aa6799615ab6.png)



####【main-2.10】rug plotとは

rugとは軸のそばについている細かいヒゲのようなもののこと
kdeで密度を見ながらrugでもどのくらい密集しているのか確認できる


```python
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm", kind="kde", rug=True)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/66c0a112-8542-4316-3043-c7a53f179215.png)



散布図と合わせたりもできる


```python
sns.scatterplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")
sns.rugplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/472e080f-24d3-2765-72d9-3f37e7a6c096.png)





####【main-2.11】横向きにplotする

histgramといえばx軸に値の入った積み上げグラフのイメージだが、
yに値を指定することで自動的に横向きに描画してくれる

```python
sns.displot(data=penguin,y='bill_depth_mm',kind='kde',hue='sex',col='island')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/fc318f55-bace-ab4f-a46f-e3b3aa4d1a94.png)


####【main-2.12】plotの小タイトルの指定

オプションの時に全体タイトルの話はした
各小タイトルを変えるにはgに一旦グラフ情報を入れてcol_nameからとってくることも可能
(くわしくはset_titlesを参照)

```python
g=sns.displot(data=penguin,y='bill_depth_mm',kind='kde',hue='sex',col='island')
g.set_titles("{col_name} penguins")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/df56d285-be72-ea99-c85a-3e9b28e24e9d.png)


####【main-2.13】ecdf累積plot


累積確率として出力できる

```python
sns.displot(data=penguin, x="flipper_length_mm", kind="ecdf")
sns.displot(data=penguin, x="flipper_length_mm", kind="ecdf",complementary=True)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9fa7bbc1-581f-f877-cb20-b9b06a72aaa9.png)

complementary=True

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2b92da59-e727-c1ca-591b-ecdebc8e26d2.png)



生存時間分析などに使えそう



####【main-2.14】描画画面を複数に分けるcol_wrapと、対数処理をするlog_scale

displotにも内部でlog処理するかを指定できる機能がある
片方の軸だけ対数処理することも可能

描画は普段colで行い自然に分割されるが、
〇列で表示したい等の指定も可能

```python
diamonds = sns.load_dataset("diamonds")
sns.displot(data=diamonds, x="depth", y="price", log_scale=(True, False), col="clarity",col_wrap=5,kind='kde')
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ad6b6ea8-3503-b9ae-563b-fe4476757c0a.png)



###【main-3】catplotによるstrip,swarm,box.box,violin,point,bar,boxen,count




####【main-3.1】catplotのデフォルト 

通常ではstripに指定されている

カテゴリーに向いた可視化ツールなので質的変数に対応させる

```python
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='strip')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/617e4ce8-7134-74cf-711e-1d38f066db13.png)




kindの種類をみていく


```python
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='box')

sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='boxen')

sns.catplot(data=penguin,x='species',height=6,kind='count')

sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='bar')

sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='violin')

sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='swarm')

sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='point')
```


box

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b5b37c8d-19c5-cea5-b968-f6b388cee84e.png)


boxen

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/eb5eeb36-9080-07c4-fbc0-8ca0d6738519.png)

count

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/36e069c8-847b-77c5-785e-e059f1be48f6.png)

bar(countのy軸を見る)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2279d825-5979-9562-1c81-2585824b7077.png)


violin

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/8666cb01-e919-638d-ec6e-35c786fc25e6.png)


swarm


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e7cbab04-915e-7720-98ca-3213ba2f67e5.png)



point
群間比較、分散分析などに使えそう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f2677104-e1d9-1f13-0a55-7f2e53b9b86b.png)


上記を見てもらって信頼区間があるのはわかってもらえたと思う
ciで設定可能




####【main-3.2】boxやviolinの表現



同じ列で描画するか、分けるか　dodge

```python
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g", hue="sex", dodge=False,height=6)
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/17200081-ea70-b001-fd87-c4cd5fbb0155.png)




```python
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g", hue="sex", dodge=True,height=6)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2ecba6f0-d97e-58db-e336-37c10b1cd32a.png)


swarmやviolinでも同じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/705fb3d8-0b42-832c-34df-f869ef0cb72f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d581fbca-0ce8-1f55-b065-d04d86f80380.png)



barでdodgeをFalseにすると混乱を招きそうな図になる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5fdfcecf-f72f-5139-4903-0ac851e8c450.png)

本当は乗っかっているのでなく後ろに隠れている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a0e87c60-b5e7-ec29-1154-43c71ee56901.png)



violinはsplitが選択できる

```python
sns.catplot(data=penguin, kind="violin",x="species", y="body_mass_g", hue="sex", split=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/6648a0fb-30b1-4c6f-9a94-fa8d4c4f6286.png)




yとxを入れ替えて横向きにもできる

```python
sns.catplot(data=penguin, kind="violin",y="species", x="body_mass_g", hue="sex", split=True)
```

 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/17428385-3a2b-885f-2824-3bb12e92f819.png)


####【main-3.3】swarmとboxやviolin

swarmは点が多くなりやすい
描画できない時、本来描画すべき点ができていないという警告を出してくれる
やさしい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b895697d-5e15-6c1d-8dc2-9557d1b0dfb4.png)


boxやviolinの後から書き足すことで、重ねて表示してくれる機能もある

```python
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g",height=6)
sns.swarmplot(data=penguin,x="species", y="body_mass_g",hue='sex',palette="Set1")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/52d2ec1d-c625-f8d9-0d68-99dda4e9286c.png)


###【adv】発展的な使い方

####【adv-1】pair plot


データフレーム全体を俯瞰するときに便利なpairを使ってみる

pairplot関数を呼んだ場合、よく見る図となるが

```python
penguin = sns.load_dataset("penguins")
sns.pairplot(penguin)

sns.pairplot(penguin, hue="species)
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2f3bde10-ed97-0370-aa19-79863668c576.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a62a5b77-b725-cc96-b9bd-6ba63f0764c9.png)







PairGridを使うと上側、下側のplot形式を改めて指定できる



```python
penguin = sns.load_dataset("penguins")

g = sns.PairGrid(penguin, diag_sharey=False)
g.map_upper(sns.scatterplot, s=15)
g.map_lower(sns.kdeplot)
g.map_diag(sns.kdeplot, lw=2)
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f6d31ece-8e6e-d390-01f8-9807c95c0f6f.png)







####【adv-2】heat map

行列形式のデータに対してheatmapを返す

```python
flights = sns.load_dataset("flights")
flights = flights.pivot("month","year", "passengers")
sns.heatmap(flights)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3f8fba46-8a21-577d-edc4-3cb317869866.png)


数値も一緒にのせたい場合はannotをTrueにして、数字が暴れないようにfmtを使う

```python
sns.heatmap(flights, annot=True, fmt="d")
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/630d01c0-600b-306e-bd6a-a80312cb8e02.png)

境界を書きたいときにはlinewidthsで指定する

```python
sns.heatmap(flights, linewidths=.5)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/dd099c16-208d-3f97-c6ec-a7d89c4ee58b.png)


numpyの三角行列を作ってくれるtriu_indices_fromを使い、
T,F 1,0で作られたような行列をmaskに入れることで、
形を整えて出力できる


```python
corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True

with sns.axes_style("white"):
    f, ax = plt.subplots(figsize=(7, 5))
    ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d70fa31f-a371-49e3-fef8-ed853968246a.png)



####【adv-3】joint plot

二つの変数間の関係を密度として見つつ、各変数の分布も確認する


```python
sns.jointplot(x='bill_length_mm', y='bill_depth_mm', data=penguin)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f6807591-3261-0a57-a7d3-0b87cfe4c855.png)

これも種類があってkindで指定することができる
デフォルトの上記はscatter

kde

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/bb95379f-84ba-16b9-c7f0-65d54ad44897.png)



hist

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b5a35555-d31a-1fd9-8dad-b09ad91552f5.png)


hex


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/0cf19890-8e30-6019-075d-792ccab86490.png)


reg(regression)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/4700eaa0-2b83-a3ac-bd9f-ef083ce0b85b.png)


residモデル残差確認のためのplot(後述)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/14c81305-51f8-9e55-e172-65fafc9c83ad.png)



jointgridを使うことで組み合わせを考えながらplotすることもできる

メインと側面の図を任意で指定する

```python
g=sns.JointGrid(x='bill_length_mm', y='bill_depth_mm', data=penguin)
g.plot(sns.regplot, sns.kdeplot)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/8465e58f-075e-07b1-f83a-2f0de1328588.png)


rugの付け足しや、散布図にkdeをかける等を
plot_jointやmarginalsを使って付け足していく

```python
g = sns.jointplot(data=penguin, x="bill_length_mm", y="bill_depth_mm")
g.plot_joint(sns.kdeplot, color="r", zorder=0, levels=6)
g.plot_marginals(sns.rugplot, color="r", height=-.15, clip_on=False)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/22baf07b-5c50-2cac-0380-1b5cd6cf2230.png)



メイン、上、右の順に指定することで任意の組み合わせをつくる


```python
g = sns.JointGrid()
x, y = penguin["bill_length_mm"], penguin["bill_depth_mm"]
sns.scatterplot(x=x, y=y, ec="b", fc="none", s=100, linewidth=1.5, ax=g.ax_joint)
sns.histplot(x=x, fill=False, linewidth=2, ax=g.ax_marg_x)
sns.kdeplot(y=y, linewidth=2, ax=g.ax_marg_y)
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9b50ea5c-7fba-7b2c-f79a-1d7847c896d3.png)






####【adv-4】linear model plot

どうやらFacetとregplotを組み合わせたものがlmplotな様子なので、基本的にlmplotで説明する
pairplotやjointplotで動いているのもregplotらしい


線形回帰を可視化

```python
sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/8bd88528-10fd-ea51-1c45-fa82269547da.png)

hueで色分け


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9c21a4cf-5026-9c11-a368-37af1d2f4673.png)




orderで多項式回帰の次数を決める



```python
sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin, order=5)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d9897292-3676-9f90-8666-896cd31717f2.png)


logisticを行うオプションもある

```python
penguin['male'] = pd.get_dummies(penguin.sex)['Male']
sns.lmplot(x='bill_length_mm', y='male',data=penguin, logistic=True)
```


モデルを作ったら残差も比較したくなる
作図したlmモデル(線形や多項式)がどれだけデータを説明できているのかについては残差確認を行う
線形モデルの判定として、残差が正規分布に従っていそうならばモデルはある程度良いモデルと判定できる


おそらくregとlmの関係からして、
jointplotの"resid"で動いている背景の関数がresidplotかな？


```python
sns.jointplot(x='bill_length_mm', y='body_mass_g', data=penguin,order=1,kind='resid')
sns.jointplot(x='bill_length_mm', y='body_mass_g', data=penguin,order=10,kind='resid')
```

1次の残差


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7b2ec851-5722-b365-3681-da110c4a501f.png)


10次の残差


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/81ca47d8-36f8-e5e7-36b0-456f2d929c44.png)





#####sklearnのモデルと比較



```python
import sklearn
from sklearn import datasets,linear_model

penguin=penguin.dropna(how='any')
model = linear_model.LinearRegression()

X = np.array(penguin["bill_length_mm"]).reshape(-1, 1)
Y = np.array(penguin["body_mass_g"]).reshape(-1, 1)
model.fit(X, Y)
pred_y = model.predict(X)

plt.scatter(x=X, y=Y-pred_y)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/262a7dbe-a397-88f4-7ba4-720e40c50e39.png)



たしかに残差を計算してくれていそう。




####【adv-5】clustermap

```python
iris = sns.load_dataset("iris")
species = iris.pop("species")
g = sns.clustermap(iris)
```

階層クラスタリングを可視化しながらしてくれる
どの距離基準でグループ化していくかはmethodで指定

このあたりは説明しんどいので階層クラスタリングを学んでもらったほうがはやい
methodはscipyの計算から取得[scipy.cluster.hierarchy.linkage](https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage
)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/6bc7fe9a-fb9f-418f-faed-31585cf34c65.png)


mathod

```
single
complete
average
weighted
centroid
median
ward
```


single

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ef346dbc-7e7a-84aa-6254-02d14de0809d.png)



#最後に

可視化方法はまだまだ紹介していく予定
コードは汚くても間違った図の使い方にはなるべく気を付けたい

#参考

[リリースnews-v0.11.0 (September 2020)](https://seaborn.pydata.org/whatsnew.html)

[API reference](http://seaborn.pydata.org/api.html)

[Announcing the release of seaborn 0.11](https://medium.com/@michaelwaskom/announcing-the-release-of-seaborn-0-11-3df0341af042)

[Overview of seaborn plotting functions](http://seaborn.pydata.org/tutorial/function_overview.html#similar-functions-for-similar-tasks)