ケース別データの可視化パターンとpythonによる実装

データが与えられた時、まずは**可視化してデータの特徴を把握すること**が大切です。しかし、**何を軸にしてどのように可視化するのか**ということに関しては、あまりルール化されていないのが現状だと思います。

データから何を知りたいのか？ということから、パターン別にどのように可視化したらいいのかということをチートシート形式で示し、さらにpythonでの可視化方法を順に紹介していきたいと思います。

<img width="965" alt="Screen Shot 2018-06-06 at 14.29.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/8332e817-92a0-7848-6d83-397b04f0c75f.png">

上のチートシートを参考に、

- Distribution｜分布
- Composition｜構成
- Relationship｜関係
- Comparison｜比較

の4つの項目に分けて、**どのようなデータパターンではどのように可視化するとわかりやすいか**、**pythonではどのように実装するのか**を記していきます。

# 準備

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

plt.style.use('ggplot')
plt.rcParams.update({'font.size':15})

%matplotlib inline
```

可視化には主に、`matplotlib.pyplot`、`seaborn`を使います。seabornに馴染みのない方は、[この記事](https://qiita.com/HiromuMasuda0228/items/babdfa175815fb3e3a94)を見るといいと思います。

# Distribution｜分布

<img width="544" alt="Screen Shot 2018-06-06 at 17.57.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/c2c9c477-0707-2f1f-6cfe-136478c3f25a.png">


## 1変数の分布
### データポイントが数個の場合｜ヒストグラム

```py
x = np.random.normal(size = 1000)

plt.hist(x)
plt.show()
```
<img width="389" alt="Screen Shot 2018-06-06 at 17.55.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/1a17f91e-6489-7b93-308c-fc6fb949f81b.png">


### データポイントが多い場合｜線グラフヒストグラム

```py
x = np.random.normal(size = 1000)

# ここのみ、seabornを用いて可視化
sns.distplot(x)
```

<img width="387" alt="Screen Shot 2018-06-06 at 17.55.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/cad26a2f-42dc-c6a4-4cd0-e6109772679f.png">


## 2変数の分布｜散布図

```py
x = range(1, 101)
y = np.random.randn(100)*15 + range(1, 101) 

plt.scatter(x, y)
plt.show()
```

<img width="393" alt="Screen Shot 2018-06-06 at 17.55.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/feb3f926-612a-1715-cd65-bdcda8a887ca.png">


# Composition｜構成

<img width="1199" alt="Screen Shot 2018-06-06 at 17.59.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/a3c22513-21c3-1ed3-d42b-d5a0d3ba1ceb.png">


## 時間ごとの構成
### 時間軸が複数個の場合
#### 割合のみを見たい場合｜累積棒グラフ

```py
x = [1, 2, 3, 4, 5]
y1 = [80, 60, 40, 20, 5]
y2 = [20, 40, 60, 80, 95]

plt.bar(x, y1)
plt.bar(x, y2, bottom=y1)
```
<img width="395" alt="Screen Shot 2018-06-06 at 18.04.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/b10ac7c2-67cc-dd1f-4209-a6c088bfe982.png">


#### 割合と値を両方見たい場合｜棒グラフ

```py
x = [1, 2, 3, 4, 5]
y1 = [100, 200, 300, 400, 500]
y2 = [1000, 800, 600, 400, 200]

plt.bar(x, y1)
plt.bar(x, y2, bottom=y1)
```
<img width="401" alt="Screen Shot 2018-06-06 at 18.04.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/e4a71ca0-a3a7-482c-332a-03a63932b54a.png">


### 時間軸が多い場合
#### 割合のみを見たい場合｜累積エリアチャート

```py
x = range(1, 7)
y1 = [0, 20, 40, 30, 40, 100]
y2 = [40, 50, 20, 40, 55, 0]
y3 = [60, 30, 40, 30, 5, 0]
 
plt.stackplot(x, y1, y2, y3)
plt.show()
```
<img width="389" alt="Screen Shot 2018-06-06 at 18.04.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/1d30e3c8-4f02-c0d8-cbf2-0098f3c2b397.png">


#### 割合と値自体を両方見たい場合｜エリアチャート

```py
x=range(1, 7)
y1=[1, 4, 6, 8, 9, 3]
y2=[2, 2, 7, 10, 12, 10]
y3=[2, 8, 5, 10, 6, 8]
 
plt.stackplot(x,y1, y2, y3)
plt.show()
```
<img width="383" alt="Screen Shot 2018-06-06 at 18.04.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/ab2fdd9e-8391-63b9-d382-f0514dcfa100.png">


## 静的カテゴリごとの構成
### 全体に占める割合を見たい場合｜円グラフ

```py
x = [100, 200, 300, 400, 500]
label = ["A", "B", "C", "D", "E"]

plt.pie(x, labels=label)
plt.axis('equal') # 出力が楕円形になるのを防ぐため
plt.show()
```
<img width="370" alt="Screen Shot 2018-06-06 at 18.04.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/f3f1ce03-cd22-36f5-cb69-9cd5aec90209.png">


### 構成の構成を見たい場合｜累積棒グラフ

```py
x = [1, 2, 3, 4, 5]
y1 = [80, 60, 40, 20, 5]
y2 = [20, 40, 60, 80, 95]

plt.bar(x, y1)
plt.bar(x, y2, bottom=y1)
```
<img width="395" alt="Screen Shot 2018-06-06 at 18.04.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/e65838a3-eb85-485a-21a0-7025e6f8bf24.png">


### 全体に対する累積値と値自体を見たい場合｜ツリーマップ

```py
import squarify

x = [13,22,35,5]
label = ["A", "B", "C", "D"]
 
squarify.plot(x, label=label)
plt.axis('off')
plt.show()
```
<img width="396" alt="Screen Shot 2018-06-06 at 18.04.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/c28792a9-88f8-7622-c9be-05cd7c59f180.png">


# Relationship｜関係

<img width="505" alt="Screen Shot 2018-06-06 at 18.09.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/f6a6aca1-bde0-04d2-18e7-3cdb9e820cbb.png">


## 変数が2つの場合｜散布図

```py
x = range(1, 101)
y = np.random.randn(100)*15 + range(1, 101) 

plt.scatter(x, y)
plt.show()
```

<img width="388" alt="Screen Shot 2018-06-06 at 18.09.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/b3cf9ac1-8d3c-7289-4399-08e08d4ae409.png">


## 変数が3つの場合｜散布図

```py
x = np.random.rand(40)
y = np.random.rand(40)
z = np.random.rand(40)
 
plt.scatter(x, y, s=z*1000, alpha=0.5)
plt.show()
```

<img width="391" alt="Screen Shot 2018-06-06 at 18.09.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/4f9de2d9-0479-0208-749a-4384cbd4a7e9.png">


# Comparison｜比較

<img width="1156" alt="Screen Shot 2018-06-06 at 18.09.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/66ad3eef-d00a-5eee-d4ca-7985b1e77e02.png">


## アイテム間の比較
### アイテムごとの1変数を比較したい場合

#### カテゴリが少ない場合｜縦棒グラフ・横棒グラフ

```py
x = [1, 2, 3, 4, 5]
y = [80, 60, 40, 20, 5]

plt.bar(x, y)
plt.show()
```
<img width="383" alt="Screen Shot 2018-06-06 at 18.10.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/ca0f8959-bc8b-b7b5-8448-12b6fc06f423.png">


```py
x = [1, 2, 3, 4, 5]
y = [80, 60, 40, 20, 5]

plt.barh(x, y)
plt.show()
```
<img width="388" alt="Screen Shot 2018-06-06 at 18.09.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/c401b631-30c0-2749-b4cf-b6d7b9110f2f.png">

#### カテゴリが多い場合

```py
iris = sns.load_dataset("iris")
sns.pairplot(iris, hue="species", size=2.5)
```
<img width="744" alt="Screen Shot 2018-06-06 at 18.25.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/68983516-2b6e-1fd0-e24f-dd1fedf06de3.png">


### アイテムごとの2変数を比較したい場合｜棒グラフ

```py
y = [3, 12, 5, 18, 45]
x = ('A', 'B', 'C', 'D', 'E')
x_width = [0.1, 0.2, 3, 1.5, 0.3]
y_pos = [0, 0.3, 2, 4.5, 5.5]

plt.bar(y_pos, y, width=x_width)
plt.xticks(y_pos, x)
plt.show()
```
<img width="395" alt="Screen Shot 2018-06-06 at 18.09.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/f7421301-f0ce-81d0-f7a9-4da6013e7f03.png">


## 時間軸による比較
### 時間軸が少ない場合
#### カテゴリが1つもしくは数個の場合｜棒グラフ

```py
x = [1, 2, 3, 4, 5]
y = [80, 60, 40, 20, 5]

plt.bar(x, y)
plt.show()
```
<img width="383" alt="Screen Shot 2018-06-06 at 18.10.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/db19b474-0bf8-e52b-3175-51b3b9ddeb59.png">


#### カテゴリが多い場合｜線グラフ

```py
x = range(1,11)
y1 = np.random.randn(10)
y2 = np.random.randn(10)+range(1,11)
y3 =  np.random.randn(10)+range(11,21)

plt.plot(x, y1)
plt.plot(x, y2)
plt.plot(x, y3)
plt.show()
```

<img width="399" alt="Screen Shot 2018-06-06 at 18.10.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/80a7d20d-aeb3-05d7-f0eb-6e4b975b1a65.png">


### 時間軸が多い場合
#### 非循環データの場合｜線グラフ

```py
y = np.cumsum(np.random.randn(1000,1))

plt.plot(y)
```

<img width="391" alt="Screen Shot 2018-06-06 at 18.10.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/108729/bf14a730-5cfc-8c74-039b-1a8b4af8aed8.png">



# 参考サイト
- [matplotlib.pyplot Documentation](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html)
- [the Python Graph Gallery](https://python-graph-gallery.com/)
- [5 Quick and Easy Data Visualizations in Python with Code](https://towardsdatascience.com/5-quick-and-easy-data-visualizations-in-python-with-code-a2284bae952f)
- [pythonでデータを可視化したいならseabornを使おう！](https://qiita.com/HiromuMasuda0228/items/babdfa175815fb3e3a94)