カラムごとの分布を、ほぼ一気に出力

# 課題提起
タテヨコのデータセットをが手元にあるとします。
強烈に大きなデータでなければ、`python`の`pandas`の`read_csv`で読んで概観を掴む時に、まずは`.describe()`で各種統計量が把握できますが、次の一手でカラムごとの分布って見たくなりません？
この記事では、`matplotlib`, `pandas plot`, `seaborn`の3つの描画ライブラリを使って、ほぼ一気に各カラムの分布を描画するコードを紹介します。

# 環境
`python 3.6`

# ライブラリ群の準備
冒頭に書いたように、`matplotlib`, `pandas`, `seaborn`を読み込んでおきます。

```py
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
```

# データの読み込み＆データフレーム作成
この例では`load_boston`をベースにしますが、自前のデータでもいいですよ。

```py
from sklearn.datasets import load_boston
X = load_boston()
X.feature_names
# array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',    'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
```

```py
df = pd.DataFrame(X.data, columns=X.feature_names)
df.head()
```
データはこんな感じ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/cab327ae-c133-e851-6d76-815a93ec1ad6.png)

で、冒頭に書いた`.describe()`をやっとくと、、

```py
df.describe()
```
こんな感じ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/59c47429-e677-b629-e32d-53247eae17da.png)

まぁ、そんなもんか、と。




# 分布を確認って？

データを見る時、字面じゃなくて絵的に見えた方が直感に訴えることもありますよね。
まずはヒストグラム、というか分布を描いてみよう、と（この記事の目標）
データセット`df`のカラム`CRIM`の分布（ヒストグラム）を確認してみます。

## matplotlibの場合

```py
plt.hist(df['CRIM'])
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/6b32ab55-60cb-50c4-69ef-623ccd7f99ff.png)


## pandas plotの場合

`pandas`の描画機能を使うと

```py
df['CRIM'].plot(kind='hist')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/85369058-042b-431f-9888-6d6dbbc0cee3.png)

## seabornの場合

なんかヤケにbinが細いな、、、

```py
sns.histplot(df['CRIM'])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/b0edfdfc-fae4-f570-36c1-59fa82e9999c.png)

ただ、カラムごとにこれやるのツラいですよね。。


# で、カラムごとの分布を出力しよう。

取り敢えず、たくさんグラフを出すので少し大きめに出力するようにしておきましょう：

```py
fig = plt.figure(figsize=(25, 25))
```

この後、先ほどと同様に3通り(`matplotlib`, `pandas plot`, `seaborn`)で一気に出力するコードを書いてみます。

## matplotlibで一気に出力

```py
for i, col in enumerate(df.columns):
    plt.subplot2grid((5, 3), (i//3, i%3))
    plt.hist(df[col])
    plt.title(col)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/24304806-06ee-86a1-6536-df6178073361.png)

### ポイント

```py
for i, col in enumerate(df.columns):
    plt.subplot2grid((5, 3), (i//3, i%3))
```
- アイデアの源泉はココ。`for`ループでカラムを1つずつ取って並べりゃいいだろう、と。`enumerate`でグラフに順番`i`を付けて描いていきます。
- `plt.subplot2grid`でそれを実現します。グリッド状に並べていきます。
    - `(5,3)`のところは、縦に`5`つ、横に`3`つ並べる、という意味。`load_boston`はカラムが`13`あります。`5 x 3=15`のグリッドを用意しておけば全部描き切れますね。
    - `(i//3, i%3)`は、グリッドの座標みたいな感じ。`i//3`は`i`を`3`で割った時の商、`i%3`は余り。イメージ的には↓な感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/6b848c18-8cd7-22e7-6a56-e81db641eff3.png)
    - 残りの`plt.hist(df[col])`で描画、`plt.title(col)`でタイトルを表示、、、てのを`col`ごとに実行します。色味を変えたり、グリッドの大きさを変えたりする場合は適宜引数を変えたり、、、などは、[Reference](https://qiita.com/kyoro1/items/dc15591468d799e36fd5#reference)を眺めてみて下さい！

## pandas plotで出力

基本的なアイデアは一緒ですが、`pandas plot`った場合のコード：

```py
for i, col in enumerate(df.columns):
    ax = plt.subplot2grid((5, 3), (i//3, i%3))
    df[col].plot(kind='hist', ax=ax)
    ax.set_title(col)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/df47956c-45df-faca-7c3a-06bd2393dd9a.png)

## seabornで出力

同じく`seaborn`だとこんな感じ：

```py
for i, col in enumerate(df.columns):
    ax = plt.subplot2grid((5, 3), (i//3, i%3))
    sns.histplot(df[col], ax=ax)
    ax.set_title(col)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80539/51fb7cb6-7917-ef94-e028-1efa91ff7976.png)


# Reference

- [subplot2grid](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplot2grid.html)

- [matplotlib.pyplot.hist](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.hist.html)

- [pandas plot](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html)

- [seaborn histplot](https://seaborn.pydata.org/generated/seaborn.histplot.html)