41
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LOBAdvent Calendar 2018

Day 14

matplotlibで自在にグラフを描画するための3ステップ(兼チートシート)

Last updated at Posted at 2018-12-13

この記事は**LOB Advent Calendar Advent Calendar 201817日目**の記事として書いています。

#はじめに

データをグラフで表現するというのは、データ分析には欠かせない要素の一つです。

よほどの天才ではない限り、普通は数値だけを見ても理解はできません。
データの状態をイメージしたり、 分析結果を直感的に理解したり、また人に説明するためにもグラフ描画のスキルは必須です。

手軽に使いたいなーと思いながらも多機能すぎてとくに初めての人には結構ハードルが高いと思います。
他の記事を見ててもアレルギー反応を起こす場合が多かったので、とっかかりとしての分かりやすい記事を目指しました。
この記事がデータ分析のはじめの一歩になれば最高です!

本記事の目的

本記事ではmatplotlibの使い方を3ステップでまとめて、ある程度、自在にグラフの描画ができるようになるまでを目的としてます。
(自分用のチートシート的な部分もありますがご容赦ください)

まずは環境を作成する必要がありますが、それは以下で記事にしてまとめておきました。
まだ環境ないよって言う人は参考にしてみてください。
[Mac/Linux] Anacondaで Python3系をインストールし Jupyter Notebook を使うまで

Step1. 描画するグラフを決定する

まずはどのようなグラフを書くかをイメージすることがとても重要です。

以下によく使うであろうグラフを一覧しておきます。(実際はもっと色々かけます)
この記事に辿り着いた人であれば、扱うデータからどのようなグラフを書くのが有用かくらいはイメージできると思いますので、まずは利用するグラフを決めましょう。

以下のグラフのサンプルソースは こちらのGist にアップしておきました。

 グラフ一覧      
g2x.png
棒グラフ(誤差ライン付) - 詳細
plt.bar(x, height)
g3x.png
横棒グラフ(誤差ライン付) - 詳細
plt.barh(width, y)
g4x.png
積み上げ棒グラフ - 詳細
plt.bar(x, height)
g5x.png
散布図 - 詳細
plt.scatter(x, y)
g6x.png
散布図(サイズ変更付) - 詳細
plt.scatter(x, y, s)
g7x.png
日付データプロット - 詳細
plt.plot_date(dates, s)
g8x.png
折れ線グラフ - 詳細
plt.plot(x)
g9x.png
円グラフ - 詳細
plt.pie(fracs, labels, autopct)
g10x.png
積上げ折れ線グラフ - 詳細
plt.stackplot(x, y1, y2, ...)
g11x.png
ヒストグラム - 詳細
plt.hist(x)
g12x.png
2次元ヒストグラム - 詳細
plt.hist2d(x, y)
g13x.png
矩形描画 - 詳細
plt.broken_barh(x, y)
g14x.png
箱ひげ - 詳細
plt.boxplot(a)
g15x.png
バイオリン図 - 詳細
plt.violinplot(data, pos)
g16x.png
等高線 - 詳細
plt.contourf(X, Y, Z)
g17x.png
離散データ - 詳細
plt.stem(x, y, '-.')
g18x.png
自己相関 - 詳細
plt.acorr(x)
g19x.png
相互相関 - 詳細
plt.xcorr(x, y)
g20x.png
疑似カラー描画 - 詳細
plt.pcolor(x, y, z)
g21x.png
ベクトル - 詳細
plt.quiver(X, Y, U, V)

グラフのサンプルソースは こちらのGist にアップしておきました。

他のグラフ

他にも本当に様々なグラフを書くことができます。知りたい場合は以下を覗いてみると良いでしょう。

Step2. データを用意しプロットする

さて書き出すグラフを決めたら、次に扱おうとしているデータを切り貼りして整形しグラフ表示用データを用意するわけなのですが、データの切り貼りは別の記事に任せることにして、ここでは用意しなければならないデータを種類別に記載をしておこうと思います。

用意しなければならないデータが理解できれば、ここに辿り着いている皆さんであればデータの整形はなんとかなるだろうという考えのもとです。

用意するデータはざっくり分けて以下の3種類のどれか

1次元のデータ

1次元のデータで表現するものには以下のようなものがあります。

  • 折れ線グラフ plt.plot(x)
  • 円グラフ plt.pie(fracs)
  • ヒストグラム plt.hist(x)
  • 自己相関 plt.acorr(x)

折れ線グラフ を例にとってソースを載せておきます。
基本的には同じような使い方なので、サンプルソースを参考にしてください。

plot.py
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()

g8.png

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)

散布図 を例にとってソースを載せておきます。
基本的には同じような使い方なので、サンプルソースを参考にしてください。

scatter.py
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()

g5.png
※上記の例ではランダムに表示しているので、バラバラですが意味のあるデータならプロットが偏ったりするんでしょうね。

その他のデータ

その他のデータで表現するものには以下のようなものがあります。
データを積み上げたり、奥行き(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)

ここでは普段使いしそうな積上げ折れ線グラフ を例にとってソースを載せておきます。
それぞれ特徴的な使い方にはなりますので、サンプルソースを参考にしてください。

stackplot.py
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()

g10.png

グラフのオプション

最終的には上記のようなデータプロットと、いくつかの関数オプションを利用して、最終的なグラフを表現することになります。

関数オプションはグラフによって様々なので、各グラフの関数詳細を参照してください。
Step1の一覧の[詳細]リンクから飛ぶか、公式のFunctionページを眺めることになります。

で、最後に表示plt.show()することでグラフが表示されるという具合です。

Step3. グラフを装飾する

Step2 までで基本的なグラフはかけるようになりました。

ちょっとデータをグラフで確認する程度であればStep2までで十分ですが、あとで見るためエビデンスとして、また人に見せるため に作ったグラフなのであれば、これでは不十分ですね。

最後にグラフの装飾方法を最後に覚えることにしましょう。

こちらの装飾もサンプルソースを こちらのGist にアップしておきました。

グラフのタイトル(title)

まずは簡単なところから。
title 関数でグラフにタイトルを埋め込みます。
1つのグラフに複数のグラフを表現することもでき、その時には suptitle 関数を利用することになります。(複数グラフの作り方は後述)

title.py
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()

t1.png

凡例の追加 (legend)

legend 関数を利用することで、凡例を表示設定することができます。

legend.py
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()

t2.png

等高線(contour)2次元ヒストグラム (hist2d) に対する、 色の凡例は colorbar 関数で表示することができます。
コードは割愛しますがこちらのサンプルページに置いておきます。
t3.png

ラベルの表示 (xlabel/ylabel)

xlabel/ylabel 関数を利用することで、ラベルを表示設定することができます。

label.py
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()

t5.png

軸の描画範囲 (xlim/ylim)

xlim/ylim 関数を利用することで、軸の描画範囲を設定することができます。(これを設定しなかった場合はグラフ全体が見えるように自動的に描画範囲が決まります)
あたりまえですが、グラフを範囲外の値やマイナス値も設定ができます。

lim.py
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()

t6.png

平行・垂直の線を引く(axhline/axvline)

axhline/axvline 関数を利用することで、ラインを引くことができます。
限界線や境界線を表現する時に使えますね。

axline.py
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()

t7.png

hlines/vlines 関数を使えば、一度に複数の平行線も引くことができます。
こちらのサンプルページに置いておきます。
t8.png

矩形の描画(axhspan/axvspan)

axhspan/axvspan 関数を利用することで、矩形を描画することができます。
これも限界線や境界線を表現する時に使う感じですかね。

axspan.py
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()

t9.png

テキストの追加(text)

text 関数でグラフにテキストを埋め込みます。
1つのグラフに複数のグラフを表現することもでき、その時には figtext 関数を利用することになります。(複数グラフの作り方は後述)

text.py
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()

t10.png

注釈の追加(annotate)

annotate 関数を利用することで、注釈を描画することができます。
これも結構使えそうですね。

annotate.py
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()

t11.png

グリッド(格子)の表示(grid)

grid 関数を利用することで、注釈を描画することができます。

grid.py
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()

t12.png

複数のグラフを表示(figure/axes)

グラフは複数のレイヤーを使って表現ができるようになっています。
Figureaxesがそれに当たり、階層構造で管理されてます。
以下の記事が分かりやすく書かれており、ここでかいつまんで書くよりも読んでもらうほうが有用だと思います。
artist.png plot.jpeg

一応、簡単なソースコードだけ載せておきます。だいたいイメージできるかと。

artist.py
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()

t13.png

もっと自在に

他にも以下のような複合的なグラフ3Dグラフも書くことができます。
g22.png g23.png

まだまだグラフマスターへの道は険しいですね (^^;
でもこの記事の延長上にこのようは複雑なグラフがあると思って問題ないと思います。

この記事が皆様のお役に経てばmm

株式会社 LOB では「流通のケタを変える、広告プラットフォームを創る」仲間を募集しています!
https://lob-inc.com/recruit/

おまけ

チートシートという意味では DataCamp が提供している有名なものがあります。こちらも参考にされると良いと思います。

参考にしたページ

41
49
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?