この記事は**LOB Advent Calendar Advent Calendar 2018の17日目**の記事として書いています。
#はじめに
データをグラフで表現するというのは、データ分析には欠かせない要素の一つです。
よほどの天才ではない限り、普通は数値だけを見ても理解はできません。
データの状態をイメージ
したり、 分析結果を直感的に理解
したり、また人に説明するため
にもグラフ描画のスキルは必須です。
手軽に使いたいなーと思いながらも多機能すぎてとくに初めての人には結構ハードルが高いと思います。
他の記事を見ててもアレルギー反応を起こす場合が多かったので、とっかかりとしての分かりやすい記事を目指しました。
この記事がデータ分析のはじめの一歩になれば最高です!
本記事の目的
本記事ではmatplotlib
の使い方を3ステップでまとめて、ある程度、自在にグラフの描画ができるようになるまでを目的としてます。
(自分用のチートシート的な部分もありますがご容赦ください)
-
Step1. 描画するグラフを決める
- 扱っているデータはどんなグラフに落としこむと分析しやすくなるかを決めます(ここを間違うとワケのわからないグラフが完成してしまう)
-
Step2. データを用意しプロットする
- 実際にグラフを作成します
-
Step3. グラフを装飾する
- 最後に人に見せるため、エビデンスのため、に見やすいグラフを作っていきます。(具体的にはタイトルや凡例、グリッドの表示など)
まずは環境を作成する必要がありますが、それは以下で記事にしてまとめておきました。
まだ環境ないよって言う人は参考にしてみてください。
[Mac/Linux] Anacondaで Python3系をインストールし Jupyter Notebook を使うまで
Step1. 描画するグラフを決定する
まずはどのようなグラフを書くかをイメージすることがとても重要です。
以下によく使うであろうグラフを一覧しておきます。(実際はもっと色々かけます)
この記事に辿り着いた人であれば、扱うデータからどのようなグラフを書くのが有用かくらいはイメージできると思いますので、まずは利用するグラフを決めましょう。
以下のグラフのサンプルソースは こちらのGist にアップしておきました。
グラフ一覧 | ||
---|---|---|
棒グラフ(誤差ライン付) - 詳細 plt.bar(x, height)
|
横棒グラフ(誤差ライン付) - 詳細 plt.barh(width, y)
|
積み上げ棒グラフ - 詳細 plt.bar(x, height)
|
散布図 - 詳細 plt.scatter(x, y)
|
散布図(サイズ変更付) - 詳細 plt.scatter(x, y, s)
|
日付データプロット - 詳細 plt.plot_date(dates, s)
|
折れ線グラフ - 詳細 plt.plot(x)
|
円グラフ - 詳細 plt.pie(fracs, labels, autopct)
|
積上げ折れ線グラフ - 詳細 plt.stackplot(x, y1, y2, ...)
|
ヒストグラム - 詳細 plt.hist(x)
|
2次元ヒストグラム - 詳細 plt.hist2d(x, y)
|
矩形描画 - 詳細 plt.broken_barh(x, y)
|
箱ひげ - 詳細 plt.boxplot(a)
|
バイオリン図 - 詳細 plt.violinplot(data, pos)
|
等高線 - 詳細 plt.contourf(X, Y, Z)
|
離散データ - 詳細 plt.stem(x, y, '-.')
|
自己相関 - 詳細 plt.acorr(x)
|
相互相関 - 詳細 plt.xcorr(x, y)
|
疑似カラー描画 - 詳細 plt.pcolor(x, y, z)
|
ベクトル - 詳細 plt.quiver(X, Y, U, V)
|
グラフのサンプルソースは こちらのGist にアップしておきました。
他のグラフ
他にも本当に様々なグラフを書くことができます。知りたい場合は以下を覗いてみると良いでしょう。
- Gallery - どんな種類があるのかはこちらを
- Pyplot function overview - Functionの詳細はこちらを
Step2. データを用意しプロットする
さて書き出すグラフを決めたら、次に扱おうとしているデータを切り貼りして整形しグラフ表示用データを用意するわけなのですが、データの切り貼りは別の記事に任せることにして、ここでは用意しなければならないデータを種類別に記載をしておこうと思います。
用意しなければならないデータが理解できれば、ここに辿り着いている皆さんであればデータの整形はなんとかなるだろうという考えのもとです。
用意するデータはざっくり分けて以下の3種類のどれか
1次元のデータ
1次元のデータで表現するものには以下のようなものがあります。
- 折れ線グラフ
plt.plot(x)
- 円グラフ
plt.pie(fracs)
- ヒストグラム
plt.hist(x)
- 自己相関
plt.acorr(x)
折れ線グラフ
を例にとってソースを載せておきます。
基本的には同じような使い方なので、サンプルソースを参考にしてください。
from matplotlib import pyplot as plt
import numpy as np
# np.random.seed(0) # ランダム値の固定
x = np.random.rand(50) #50個のランダムな数値
plt.plot(x)
plt.show()
2次元のデータ
2次元のデータで表現するものには以下のようなものがあります。
- 棒グラフ(誤差ライン付)
plt.bar(x, height)
- 横棒グラフ(誤差ライン付)
plt.barh(width, y)
- 積み上げ棒グラフ
plt.bar(x, height)
- 散布図
plt.scatter(x, y)
- 散布図(サイズ変更付)
plt.scatter(x, y, s)
- 日付データプロット
plt.plot_date(dates, s)
- 2次元ヒストグラム
plt.hist2d(x, y)
- 離散データ
plt.stem(x, y, '-.')
- 相互相関
plt.xcorr(x, y)
散布図
を例にとってソースを載せておきます。
基本的には同じような使い方なので、サンプルソースを参考にしてください。
import numpy as np
import matplotlib.pyplot as plt
# np.random.seed(0) # ランダム値の固定をしたい場合は有効にする
N = 50
x = np.random.rand(N) #50個のランダムな数値
y = np.random.rand(N)
plt.scatter(x, y, alpha=0.5) #alphaは透過率
plt.show()
※上記の例ではランダムに表示しているので、バラバラですが意味のあるデータならプロットが偏ったりするんでしょうね。
その他のデータ
その他のデータで表現するものには以下のようなものがあります。
データを積み上げたり、奥行き(z軸)があったり、ベクトルがあったりといった感じでしょうか。
グラフの意味を理解して利用しましょう。
- 積上げ折れ線グラフ
plt.stackplot(x, y1, y2, ...)
- 矩形描画
plt.broken_barh(x, y)
- 箱ひげ
plt.boxplot(a)
- バイオリン図
plt.violinplot(data, pos)
- 等高線
plt.contourf(X, Y, Z)
- 疑似カラー描画
plt.pcolor(x, y, z)
- ベクトル
plt.quiver(X, Y, U, V)
ここでは普段使いしそうな積上げ折れ線グラフ
を例にとってソースを載せておきます。
それぞれ特徴的な使い方にはなりますので、サンプルソースを参考にしてください。
import numpy as np
from matplotlib import pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [1, 1, 2, 3, 5]
y2 = [0, 4, 2, 6, 8]
y3 = [1, 3, 5, 7, 9]
plt.stackplot(x, y1, y2, y3)
plt.show()
グラフのオプション
最終的には上記のようなデータプロットと、いくつかの関数オプションを利用して、最終的なグラフを表現することになります。
関数オプションはグラフによって様々なので、各グラフの関数詳細を参照してください。
Step1
の一覧の[詳細]リンクから飛ぶか、公式のFunctionページを眺めることになります。
で、最後に表示plt.show()
することでグラフが表示されるという具合です。
Step3. グラフを装飾する
Step2
までで基本的なグラフはかけるようになりました。
ちょっとデータをグラフで確認する程度であればStep2
までで十分ですが、あとで見るため
やエビデンスとして
、また人に見せるため
に作ったグラフなのであれば、これでは不十分ですね。
最後にグラフの装飾方法を最後に覚えることにしましょう。
こちらの装飾もサンプルソースを こちらのGist にアップしておきました。
グラフのタイトル(title)
まずは簡単なところから。
title
関数でグラフにタイトルを埋め込みます。
1つのグラフに複数のグラフを表現することもでき、その時には suptitle
関数を利用することになります。(複数グラフの作り方は後述)
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(5) # 0~5の等差数列
y = (4, 1, 3, 2, 5)
width = 0.5
plt.bar(x, y, width, align='center') #棒グラフの描画
plt.title('This is title') #タイトルを設定
plt.show()
凡例の追加 (legend)
legend
関数を利用することで、凡例を表示設定することができます。
import numpy as np
from matplotlib import pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [1, 1, 2, 3, 5]
y2 = [0, 4, 2, 6, 8]
y3 = [1, 3, 5, 7, 9]
plt.stackplot(x, y1, y2, y3) #積上げ折れ線グラフの描画
plt.legend(['dataA', 'dataB', 'dataC']) # 凡例を設定
plt.show()
等高線(contour)
や2次元ヒストグラム (hist2d)
に対する、 色の凡例は colorbar
関数で表示することができます。
コードは割愛しますがこちらのサンプルページに置いておきます。
ラベルの表示 (xlabel/ylabel)
xlabel/ylabel
関数を利用することで、ラベルを表示設定することができます。
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0) # ランダム値の固定
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
area = (30 * np.random.rand(N))**2
plt.scatter(x, y, s=area, alpha=0.5) # 散布図の表示
plt.xlabel("Label X") #ラベルXを設定
plt.ylabel("Label Y") #ラベルYを設定
plt.show()
軸の描画範囲 (xlim/ylim)
xlim/ylim
関数を利用することで、軸の描画範囲を設定することができます。(これを設定しなかった場合はグラフ全体が見えるように自動的に描画範囲が決まります)
あたりまえですが、グラフを範囲外の値やマイナス値も設定ができます。
from matplotlib import pyplot as plt
import numpy as np
# np.random.seed(0) # ランダム値の固定
x = np.random.rand(50)
plt.plot(x) # 折れ線グラフを表示
plt.xlim(10, 40) # X軸の描画範囲
plt.ylim(-4.0, 2.0) # Y軸の描画範囲
plt.show()
平行・垂直の線を引く(axhline/axvline)
axhline/axvline
関数を利用することで、ラインを引くことができます。
限界線や境界線を表現する時に使えますね。
import numpy as np
import matplotlib.pyplot as plt
plt.axhline(y=0.5, xmin=0.1, xmax=0.9) # 水平線を引く
plt.axvline(x=0.5, ymin=0.1, ymax=0.9, color='r', linewidth=4) # 垂直線を引く(赤線、少し太く)
plt.show()
hlines/vlines
関数を使えば、一度に複数の平行線も引くことができます。
こちらのサンプルページに置いておきます。
矩形の描画(axhspan/axvspan)
axhspan/axvspan
関数を利用することで、矩形を描画することができます。
これも限界線や境界線を表現する時に使う感じですかね。
import numpy as np
import matplotlib.pyplot as plt
plt.axhspan(1.0, 3.0, facecolor='g', alpha=0.5) # 矩形の描画(1.0〜3.0で塗りつぶし)
plt.axvspan(2.0, 5.0, facecolor='b', alpha=0.5) # 矩形の描画(1.0〜3.0で塗りつぶし)
plt.xlim(0, 10) # X軸の描画範囲(分かりやすいように)
plt.ylim(0, 10) # Y軸の描画範囲(分かりやすいように)
plt.show()
テキストの追加(text)
text
関数でグラフにテキストを埋め込みます。
1つのグラフに複数のグラフを表現することもでき、その時には figtext
関数を利用することになります。(複数グラフの作り方は後述)
from matplotlib import pyplot as plt
plt.text(0.2, 0.5, "Test", size=20, rotation=20., ha="center", va="center")
plt.text(0.6, 0.5, "Sample", size=20, rotation=20., ha="center", va="center")
plt.show()
注釈の追加(annotate)
annotate
関数を利用することで、注釈を描画することができます。
これも結構使えそうですね。
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
# xycoordsがデフォルトの'data'なので、
# 座標(4, 1)のデータに対して座標(3, 1.5)にテキストを表示して
# 矢印で線を引っ張る
arrow=dict(facecolor='black', shrink=0.05)
ax.annotate('max', xy=(4, 1), xytext=(3, 1.5), arrowprops=arrow)
ax.set_ylim(-2,2)
plt.show()
グリッド(格子)の表示(grid)
grid
関数を利用することで、注釈を描画することができます。
import numpy as np
import matplotlib.pyplot as plt
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(100)
plt.hist(x, 50, density=True, alpha=0.75) # ヒストブラムの用事
plt.grid(linestyle='-', linewidth=1) #グリッドの表示
plt.show()
複数のグラフを表示(figure/axes)
グラフは複数のレイヤーを使って表現ができるようになっています。
Figure
やaxes
がそれに当たり、階層構造で管理されてます。
以下の記事が分かりやすく書かれており、ここでかいつまんで書くよりも読んでもらうほうが有用だと思います。
一応、簡単なソースコードだけ載せておきます。だいたいイメージできるかと。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4
fig = plt.figure()
# 左上
ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(x, y1)
# 右上
ax2 = fig.add_subplot(2, 2, 2)
ax2.plot(x, y2)
# 左下
ax3 = fig.add_subplot(2, 2, 3)
ax3.plot(x, y3)
# 右下
ax4 = fig.add_subplot(2, 2, 4)
ax4.plot(x, y4)
plt.show()
もっと自在に
他にも以下のような複合的なグラフや3Dグラフも書くことができます。
まだまだグラフマスターへの道は険しいですね (^^;
でもこの記事の延長上にこのようは複雑なグラフがあると思って問題ないと思います。
この記事が皆様のお役に経てばmm
株式会社 LOB では「流通のケタを変える、広告プラットフォームを創る」仲間を募集しています!
https://lob-inc.com/recruit/
おまけ
チートシートという意味では DataCamp が提供している有名なものがあります。こちらも参考にされると良いと思います。