【Matplotlib】色々な種類のグラフを描画する方法 

## 【はじめに】

Pythonライブラリの「Matplotlib」には、描画できるグラフの種類がいくつかあります。

どのグラフを使った方が良いのか分からない方のために、利用用途に応じたグラフの種類を紹介していきます。

### 本記事の内容

- グラフの種類と利用用途
- Matplotlibをインポート
- 使用するデータを読み込む
- 棒グラフを作成する | bar/barh
- 散布図を作成する | scatter
- ヒストグラムを作成する | hist
- 箱ひげ図を作成する | boxplot


## 【グラフの種類と利用用途】

統計では得られた結果を、その目的に合わせて上手に使うことが重要です
自分が伝えたい目的に応じて、適切なグラフを使うことにより、説明力が高まります。
グラフの種類と利用用途については次のURLが参考になると思います。

https://www.stat.go.jp/teacher/graph.html

今回は、次のグラフについて紹介します。

| 種類         | 利用用途                       | 利用シーンの例         | 
| ------------ | ------------------------------ | ---------------------- | 
| 棒グラフ     | データ間の数量の大きさの比較   | 部門別の売上の比較     | 
| 散布図       | 2種類のデータの相関の確認      | 商品の売上と気温の関係 | 
| ヒストグラム | データのばらつき（分布）の確認 | 製品の品質の確認       | 
| 箱ひげ図     | データのばらつき（分布）の確認 | 製品の品質の確認       | 

## 【Matplotlibをインポート】

Matplotlibの中のpyplotを読み込みます。
また、Jupyter Notebook内にグラフを出力させるために`%matplotlib inline`を記述します。
日本語に対応できるように`japanize_matplotlib`も読み込みます。

```Python
import matplotlib.pyplot as plt
%matplotlib inline
import japanize_matplotlib
```

## 【使用するデータを読み込む】

Pythonライブラリである「Pandas」をインポートしてcsvファイルをDataFrameとして読み込みます。

```Python
import pandas as pd
```

## 【棒グラフを作成する | bar/barh】

`plt.bar()`の引数にX軸とY軸とするカラムを指定します。
`plt.show()`とすることで、グラフを表示します。
使用するデータは、「1920年から2015年までの全国の人口推移のデータ」とします。

私のGitHubに「data.csv」としてアップロードしてあるので、下記コマンドでダウンロードすれば簡単に準備できます。

```Shell
$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Matplotlib&Seaborn/data.csv -O
```

```Python
df = pd.read_csv('data.csv', encoding='shift-jis')
df.head()
```

| 都道府県コード | 都道府県名 | 元号   | 和暦（年） | 西暦（年） | 人口（総数） | 人口（男） | 人口（女） | 
| -------------- | ---------- | ------ | ---------- | ---------- | ------------ | ---------- | ---------- | 
| 0              | 1          | 北海道 | 大正       | 9.0        | 1920.0       | 2359183    | 1244322    | 1114861 | 
| 1              | 2          | 青森県 | 大正       | 9.0        | 1920.0       | 756454     | 381293     | 375161 | 
| 2              | 3          | 岩手県 | 大正       | 9.0        | 1920.0       | 845540     | 421069     | 424471 | 
| 3              | 4          | 宮城県 | 大正       | 9.0        | 1920.0       | 961768     | 485309     | 476459 | 
| 4              | 5          | 秋田県 | 大正       | 9.0        | 1920.0       | 898537     | 453682     | 444855 | 

「平成27年」の各都道府県の「人口（総数）」を抽出して、新たなDataFrameにします。

X軸に「都道府県名」、Y軸に「人口（総数）」を指定して、各都道府県の人口（総数）をグラフにしてみます。

```Python
df_bar = df[df['西暦（年）']==2015.0]
df_bar.head(10)
```

|     | 都道府県コード | 都道府県名 | 元号 | 和暦（年） | 西暦（年） | 人口（総数） | 人口（男） | 人口（女） | 
| --- | -------------- | ---------- | ---- | ---------- | ---------- | ------------ | ---------- | ---------- | 
| 892 | 1              | 北海道     | 平成 | 27         | 2015       | 5381733      | 2537089    | 2844644    | 
| 893 | 2              | 青森県     | 平成 | 27         | 2015       | 1308265      | 614694     | 693571     | 
| 894 | 3              | 岩手県     | 平成 | 27         | 2015       | 1279594      | 615584     | 664010     | 
| 895 | 4              | 宮城県     | 平成 | 27         | 2015       | 2333899      | 1140167    | 1193732    | 
| 896 | 5              | 秋田県     | 平成 | 27         | 2015       | 1023119      | 480336     | 542783     | 
| 897 | 6              | 山形県     | 平成 | 27         | 2015       | 1123891      | 540226     | 583665     | 
| 898 | 7              | 福島県     | 平成 | 27         | 2015       | 1914039      | 945660     | 968379     | 
| 899 | 8              | 茨城県     | 平成 | 27         | 2015       | 2916976      | 1453594    | 1463382    | 
| 900 | 9              | 栃木県     | 平成 | 27         | 2015       | 1974255      | 981626     | 992629     | 
| 901 | 10             | 群馬県     | 平成 | 27         | 2015       | 1973115      | 973283     | 999832     | 

```Python
x = df_bar['都道府県名']
y = df_bar['人口（総数）']

plt.figure(figsize=(16,10))
plt.bar(x, y)
plt.title('2015年の各都道府県の人口比較')
plt.xlabel('都道府県名')
plt.ylabel('人口（総数）')
plt.xticks(rotation=90)
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/b31cd84d0bf7eb8ac16dfd538c44221d.png)](https://gyazo.com/b31cd84d0bf7eb8ac16dfd538c44221d)

**ポイント**

`plt.xticks()`の引数`rotation`に90を指定することで、X軸の都道府県を縦書きにすることが出来ます。
`plt.bar()`の代わりに`plt.barh()`とすることで、横棒グラフにします。

```Python
plt.figure(figsize=(16,10))
plt.barh(x, y)
plt.title('2015年の各都道府県の人口比較')
plt.xlabel('都道府県名')
plt.ylabel('人口（総数）')
plt.xticks(rotation=90)
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/03f58e6c43501254ec30d2798d930c97.png)](https://gyazo.com/03f58e6c43501254ec30d2798d930c97)

## 【散布図を作成する | scatter】

`plt.scatter()`の引数にX軸とY軸とするカラムを指定します。
`plt.show()`とすることで、グラフを表示します。
使用データは「2021年の東京都豊島区の不動産の取引価格情報」とします。

私のGitHubに「data2.csv」としてアップロードしてあるので、下記コマンドでダウンロードすれば簡単に準備できます。

```Shell
$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Matplotlib&Seaborn/data2.csv -O
```

```Python
df_house = pd.read_csv('data2.csv', encoding='utf-8', index_col=0)
df_house.head()
```

|     | 種類             | 地区名 | 最寄駅 | 最寄駅からの距離（分） | 取引価格（総額） | 面積（㎡） | 建築年 | 
| --- | ---------------- | ------ | ------ | ---------------------- | ---------------- | ---------- | ------ | 
| 0   | 宅地(土地と建物) | 池袋   | 池袋   | 8                      | 1200000000       | 440        | 1997   | 
| 1   | 中古マンション等 | 池袋   | 池袋   | 11                     | 18000000         | 15         | 1991   | 
| 2   | 中古マンション等 | 池袋   | 池袋   | 11                     | 24000000         | 20         | 2011   | 
| 3   | 中古マンション等 | 池袋   | 池袋   | 11                     | 25000000         | 30         | 1991   | 
| 4   | 中古マンション等 | 池袋   | 池袋   | 11                     | 24000000         | 20         | 2011   | 

「面積（㎡）」が広いほど、「取引価格（総額）」が高くなるのか、散布図にしてみます。

```Python
x = df_house['面積（㎡）']
y = df_house['取引価格（総額）']

plt.figure(figsize=(16,10))
plt.scatter(x, y)
plt.xlabel('面積（㎡）')
plt.ylabel('取引価格（総額）')
plt.title('面積と取引価格の相関')
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/f7c4db7592560ad0147a4b69cc1b617d.png)](https://gyazo.com/f7c4db7592560ad0147a4b69cc1b617d)

面積に開きがあまりがみられませんが、面積が広いと取引価格が高いことは見て分かります。

次に「建築年」が新しいほど、「取引価格（総額）」が高くなるのか、散布図にしてみます。

```Python
x = df_house['建築年']
y = df_house['取引価格（総額）']

plt.figure(figsize=(16,10))
plt.scatter(x, y)
plt.xlabel('建築年')
plt.ylabel('取引価格（総額）')
plt.title('建築年と取引価格の相関')
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/053ae59c9f00d660e972f3dcacd8febd.png)](https://gyazo.com/053ae59c9f00d660e972f3dcacd8febd)

築年数は特に取引価格にあまり影響しないことが分かりますね。

次に、「最寄駅からの距離（分）」が近いほど、取引価格が高くなるのか、散布図にしてみます。

```Python
x = df_house['最寄駅からの距離（分）']
y = df_house['取引価格（総額）']

plt.figure(figsize=(16,10))
plt.scatter(x, y)
plt.xlabel('最寄駅からの距離（分）')
plt.ylabel('取引価格（総額）')
plt.title('最寄駅からの距離と取引価格の相関')
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/b15acaec631325600e77290bc3af2f64.png)](https://gyazo.com/b15acaec631325600e77290bc3af2f64)

築年数と同様に、最寄駅からに距離も特に取引価格にあまり影響しないことが分かりますね。

## 【ヒストグラムを作成する | hist】

`plt.hist()`の引数にX軸とするカラムを指定します。
`plt.show()`とすることで、グラフを表示します。
使用データは「2021年の東京都豊島区の不動産の取引価格情報」とします。

X軸に「面積（㎡）」の階級を、Y軸にその階級に含まれるデータの数をとって棒グラフで表します。

```Python
df_house.head()
```

|     | 種類             | 地区名 | 最寄駅 | 最寄駅からの距離（分） | 取引価格（総額） | 面積（㎡） | 建築年 | 
| --- | ---------------- | ------ | ------ | ---------------------- | ---------------- | ---------- | ------ | 
| 0   | 宅地(土地と建物) | 池袋   | 池袋   | 8                      | 1200000000       | 440        | 1997   | 
| 1   | 中古マンション等 | 池袋   | 池袋   | 11                     | 18000000         | 15         | 1991   | 
| 2   | 中古マンション等 | 池袋   | 池袋   | 11                     | 24000000         | 20         | 2011   | 
| 3   | 中古マンション等 | 池袋   | 池袋   | 11                     | 25000000         | 30         | 1991   | 
| 4   | 中古マンション等 | 池袋   | 池袋   | 11                     | 24000000         | 20         | 2011   | 

```Python
x = df_house['最寄駅']
x.value_counts()
```

```
20    225
15     50
50     44
25     40
65     37
Name: 面積（㎡）, dtype: int64
```

```Python
plt.figure(figsize=(16,10))
plt.hist(x, bins=50)
plt.xlabel('面積')
plt.ylabel('不動産数')
plt.xticks(rotation=90)
plt.title('面積と不動産数')
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/31464590b909294d549d58403ba614af.png)](https://gyazo.com/31464590b909294d549d58403ba614af)

**ポイント**

ヒストグラムを作成する場合は、データの階級に対して含まれるデータ数をグラフにするため「x軸」の指定のみとなります。

## 【箱ひげ図を作成する | boxplot】

`plt.boxplot()`の引数にカラムを指定します。
`plt.show()`とすることで、グラフを表示します。

一番上の横線を最大値、一番下の横線を最小値、中央の線を中央値といいます。
また、箱の両端は、それぞれ上の中央値・下の中央値を示します。
なお、丸は外れ値といって、値に含まれません。

使用データは「2021年の東京都豊島区の不動産の取引価格情報」とします。
「最寄駅」に対して、「取引価格（総額）」の分布を箱ひげ図にしてみます。

```Python
x1 = df_house[df_house['最寄駅']=='池袋']
x2 = df_house[df_house['最寄駅']=='大塚(東京)']
x1 =x1['取引価格（総額）']
x2 =x2['取引価格（総額）']

plt.ylim(10000000, 100000000)

plt.boxplot([x1, x2])
plt.show()
```

[![Image from Gyazo](https://i.gyazo.com/8d0cf2c0625981dae9be35d4c09de2bb.png)](https://gyazo.com/8d0cf2c0625981dae9be35d4c09de2bb)

**ポイント**

箱ひげ図は同一の条件に含まれるデータに対しての範囲を表します。
※1日に対する、「始値」、「最高値」、「最安値」、「終値」、など、株価などによく使われます。

今回のデータではあまり有効なグラフではなさそうです。

## 【おわりに】

今回は、「棒グラフ」、「散布図」、「ヒストグラム」、「箱ひげ図」の描画方法を紹介しました。
どのグラフでデータを可視化すれば良いかは、実際にデータに触れながらで出ないと覚えられません。

次のサイトは公式のデータセットが多くありますので、ダウンロードしてデータ加工から練習してみるのも良いと多います。

https://www.e-stat.go.jp/

また、使用したCSVファイルやJupyter NotebookはGitHubに公開しています。
Jupyter Notebookは下記コマンドでダウンロードできるので、自由に使って是非練習してみてください。

```Shell
$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Matplotlib%26Seaborn/Matplotlibで色々なグラフを描画する.ipynb -O
```

https://github.com/nakachan-ing/python-references/tree/master/Matplotlib&Seaborn