Python
matplotlib
データ分析
Python3
データ可視化

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

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

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

Screen Shot 2018-06-06 at 14.29.04.png

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

  • Distribution|分布
  • Composition|構成
  • Relationship|関係
  • Comparison|比較

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

準備

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.pyplotseabornを使います。seabornに馴染みのない方は、この記事を見るといいと思います。

Distribution|分布

Screen Shot 2018-06-06 at 17.57.06.png

1変数の分布

データポイントが数個の場合|ヒストグラム

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

plt.hist(x)
plt.show()

Screen Shot 2018-06-06 at 17.55.10.png

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

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

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

Screen Shot 2018-06-06 at 17.55.15.png

2変数の分布|散布図

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

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

Screen Shot 2018-06-06 at 17.55.21.png

Composition|構成

Screen Shot 2018-06-06 at 17.59.41.png

時間ごとの構成

時間軸が複数個の場合

割合のみを見たい場合|累積棒グラフ

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)

Screen Shot 2018-06-06 at 18.04.21.png

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

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)

Screen Shot 2018-06-06 at 18.04.26.png

時間軸が多い場合

割合のみを見たい場合|累積エリアチャート

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()

Screen Shot 2018-06-06 at 18.04.31.png

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

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()

Screen Shot 2018-06-06 at 18.04.35.png

静的カテゴリごとの構成

全体に占める割合を見たい場合|円グラフ

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

plt.pie(x, labels=label)
plt.axis('equal') # 出力が楕円形になるのを防ぐため
plt.show()

Screen Shot 2018-06-06 at 18.04.39.png

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

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)

Screen Shot 2018-06-06 at 18.04.21.png

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

import squarify

x = [13,22,35,5]
label = ["A", "B", "C", "D"]

squarify.plot(x, label=label)
plt.axis('off')
plt.show()

Screen Shot 2018-06-06 at 18.04.43.png

Relationship|関係

Screen Shot 2018-06-06 at 18.09.25.png

変数が2つの場合|散布図

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

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

Screen Shot 2018-06-06 at 18.09.45.png

変数が3つの場合|散布図

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()

Screen Shot 2018-06-06 at 18.09.49.png

Comparison|比較

Screen Shot 2018-06-06 at 18.09.32.png

アイテム間の比較

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

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

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

plt.bar(x, y)
plt.show()

Screen Shot 2018-06-06 at 18.10.03.png

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

plt.barh(x, y)
plt.show()

Screen Shot 2018-06-06 at 18.09.58.png

カテゴリが多い場合

iris = sns.load_dataset("iris")
sns.pairplot(iris, hue="species", size=2.5)

Screen Shot 2018-06-06 at 18.25.40.png

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

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()

Screen Shot 2018-06-06 at 18.09.53.png

時間軸による比較

時間軸が少ない場合

カテゴリが1つもしくは数個の場合|棒グラフ

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

plt.bar(x, y)
plt.show()

Screen Shot 2018-06-06 at 18.10.03.png

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

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()

Screen Shot 2018-06-06 at 18.10.25.png

時間軸が多い場合

非循環データの場合|線グラフ

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

plt.plot(y)

Screen Shot 2018-06-06 at 18.10.20.png

参考サイト