Matplotlibの便利な機能

Matplotlibはとっても便利なんですが、機能がありすぎて大変です。少しずつまとめていきたいと思います。
グラフ作成時の便利な機能
subplot グラフを分ける
グラフを分けて描く時はsubplotを使います。
import matplotlib.pyplot as plt
plt.subplot(2,3,1)
plt.subplot(2,3,2)
plt.subplot(2,3,3)
plt.subplot(2,3,4)
plt.subplot(2,3,5)
plt.subplot(2,3,6)
【実行結果】

tight_layout グラフの間隔を調整
グラフの間隔を調整します。グラフが重なり合った時などの調整に便利。
tight_layout( pad=1.08, h_pad=None, w_pad=None, rect=None )
pad | (オプション) グラフの周囲の間隔を調整 |
h_pad | (オプション) 上下のグラフの幅を調整 |
w_pad | (オプション) 横のグラフの幅を調整 |
rect | (オプション) 各グラフの端をタプル(left, bottom, right, top)で調整(下記参照) |
rectの(left, bottom, right, top)はそれぞれ左下と右上を表している。

import matplotlib.pyplot as plt
ax1= plt.subplot(2,3,1)
ax1.set_xlabel('xlabel1')
ax1.set_ylabel('ylabel1')
ax2 = plt.subplot(2,3,2)
ax2.set_xlabel('xlabel2')
ax2.set_ylabel('ylabel2')
ax3 = plt.subplot(2,3,3)
ax3.set_xlabel('xlabel3')
ax3.set_ylabel('ylabel3')
ax4 = plt.subplot(2,3,4)
ax4.set_xlabel('xlabel4')
ax4.set_ylabel('ylabel4')
ax5 = plt.subplot(2,3,5)
ax5.set_xlabel('xlabel5')
ax5.set_ylabel('ylabel5')
ax6 = plt.subplot(2,3,6)
ax6.set_xlabel('xlabel6')
ax6.set_ylabel('ylabel6')
plt.tight_layout(pad=1.5,rect=(0,0,1,0.8))
【実行結果】

savefig 保存します
グラフをデータに保存します。
savefig( ファイル名 , [※bbox_inches="tight"] )
※保存したグラフのx軸が切れる場合はtightを指定します。
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
X = np.arange(0,100,0.1)
Y = norm.pdf(X,50,20)
plt.plot(X,Y,color='b')
plt.savefig('graph_save.png')
【実行結果】

fill_between 部分的に色をつける
描画したグラフに色をつけてみます。
fill_between( x, y1, y2, where, alpha )
x | x軸の範囲 |
y1 | y軸の上側 |
y2 | y軸の下側 |
where | 塗りつぶす範囲 複数の条件がある場合は"&"または"|"で指定 【例】where=(1<x) & (x<3) または where=(1>x) | (x>3) |
alpha | 塗りつぶす色の透過度 |
上側5%点の面積(確率)を塗りつぶしてみます。
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
# 上側5%点
p = norm.ppf( 0.95 , loc=0, scale=1)
# 0から100まで0.1間隔のリスト
X = np.arange(-5,5,0.1)
# 確率密度関数にX,平均0、標準偏差1の標準正規分布
Y = norm.pdf(X,0,1)
# 標準正規分布の描画
fig, ax = plt.subplots(1, 1)
ax.plot(X,Y,color='r')
y = 0
# 標準正規分布とy=0の直線に挟まれた上側5%点(p)以上の面積(確率)を塗りつぶします
ax.fill_between( X, Y, y, where=X>p)
【実行結果】

選択した範囲を塗りつぶします。
※fill_betweenの引数where句の"&"がポイントです。
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
# 0から100まで0.1間隔のリスト
X = np.arange(-5,5,0.1)
# 確率密度関数にX,平均0、標準偏差1の標準正規分布
Y = norm.pdf(X,0,1)
# 標準正規分布の描画
fig, ax = plt.subplots(1, 1)
ax.plot(X,Y,color='r')
y = 0
# -1から1.5の範囲を塗りつぶし
ax.fill_between( X, Y, y, where=(-1<X) & (X<1.5))
【実行結果】

両側を塗りつぶします。
※fill_betweenの引数where句の"|"がポイントです。
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
# 両側5%点の上側
p_u = norm.ppf( 0.975, loc=0, scale=1)
# 両側5%点の下側
p_d = norm.ppf( 0.025 , loc=0, scale=1)
# 0から100まで0.1間隔のリスト
X = np.arange(-5,5,0.1)
# 確率密度関数にX,平均0、標準偏差1の標準正規分布
Y = norm.pdf(X,0,1)
# 標準正規分布の描画
fig, ax = plt.subplots(1, 1)
# 目盛りと値を付加
ax.set_xticks([p_d,p_u])
ax.plot(X,Y,color='r')
y = 0
# 標準正規分布とy=0の直線に挟まれた両側5%点の上側5%点(p_u)以上、両側5%点の下側5%点(p_d)以下の面積(確率)を塗りつぶします
ax.fill_between( X, Y, y, where=(X>p_u) | (X<p_d))
【実行結果】

信頼区間95%を塗りつぶし
※塗りつぶす範囲をnp.linspaceによりxの範囲を指定し、指定したxの範囲を元にnorm.pdfでyの範囲を指定
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
# interval 両側(1-α)%点
down,up = norm.interval(alpha=0.95, loc=0, scale=1)
# 0から100まで0.1間隔のリスト
X = np.arange(-5,5,0.1)
# 確率密度関数にX,平均0、標準偏差1の標準正規分布
Y = norm.pdf(X,0,1)
# 標準正規分布の描画
fig, ax = plt.subplots(1, 1)
# 目盛りと値を付加
ax.set_xticks([down,up])
ax.plot(X,Y,color='r')
# 文字の挿入
ax.text(-1.0, 0.15, "95%", size = 30, color = "white")
# 塗りつぶす範囲を指定
filled_x = np.linspace(down,up,1000)
y = 0
# 両側5%点(信頼区間95%)を塗りつぶし
ax.fill_between( filled_x, norm.pdf(filled_x,0,1))
【実行結果】

GridSpec 複雑なグラフの配置
グラフを複雑な形状に配置する時はGridSpecを使います。
GridSpec( nrows, ncols, wspace, hspace )
nrows | 行数 |
ncols | 列数 |
wspace | (オプション)横幅の間隔 |
hspace | (オプション)縦幅の間隔 |
import matplotlib.pyplot as plt
grid = plt.GridSpec( 2, 3, wspace=0.4, hspace=0.3 )
plt.subplot(grid[0, 0]) # [0,0]にグラフ描画
plt.subplot(grid[0, 1:]) # [0,1][0,2]にグラフ描画
plt.subplot(grid[1, :2]) # [1,0][1,1]にグラフ描画
plt.subplot(grid[1, 2]) # [1,2]にグラフ描画

set_xlim,set_ylim グラフの軸の幅を指定
グラフのx軸、y軸それぞれの幅の大きさを指定します。
set_xlim( left, right, auto )
set_ylim( bottom, top, auto )
left,right | (オプション)グラフの左右の値を設定 |
bottom,top | (オプション)グラフの上下の値を設定 |
auto | (オプション)グラフの上下左右の値を自動で設定 autoを設定した場合、left,right,bottom,topは無効になる |
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-3, 3, 0.1)
y = np.sin(x)
fig, ax = plt.subplots()
ax.set_xlim(-4, 4)
ax.set_ylim(-2, 2)
plt.plot(x, y)
【実行結果】

annotate 注釈を入れる
グラフに注釈を入れるにはannotateを使います。
annotate( text, xy, xytext, arrowprops )
text | 注釈を入れる文字列 |
xy | 注釈の場所又は起点(矢印の先端等)を指定 |
xytext | (オプション)注釈の場所を指定。これを指定した場合はxyは起点になる。 |
arrowprops | (オプション)矢印の使用と大きさの指定。指定は辞書型。 width:矢印の幅指 headwidth:矢印の先端の幅 headlength:矢印の先端の長さ |
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
arrowprops_dict = dict(
width=5,
headwidth=15,
headlength=30,
)
ax.annotate("X", xy=(3, 4), xytext=(6, 7), arrowprops=arrowprops_dict,
color="red", size=40)
plt.show()
【実行結果】

grid グラフに目盛線を記載
グラフ内のx軸、y軸に対して目盛線を記載します。
grid( b=None, which=’major’, axis=’both’, **kwargs )
b | (オプション)kwargsを使用するか |
which | (オプション)目盛線の種類の選択 major:主目盛り線 minor:補助目盛り線 both:両方 |
axis | (オプション)軸の選択 {'both’, 'x’, 'y’} |
kwargs | (オプション)プロパティによるgridの設定 color:色の設定 alpha:透過の設定 linestyle:線の種類 |
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-3, 3, 0.1)
y = np.sin(x)
fig, ax = plt.subplots()
ax.set_xlim(-4, 4)
ax.set_ylim(-2, 2)
plt.plot(x, y)
plt.grid(color="green", alpha = 0.3, linestyle = "--")
【実行結果】

twinx グラフを重ねてy軸を2軸化
x軸のデータは共通でy軸のデータが異なる2種類のグラフを重ね合わせるには、twinxを使います。
seabornでもy軸の2軸化を試みましたがやり方がわからなかったので(方法はあるかもしれませんが)、2軸化はmatplotlibのtwinxが役立つと思います。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import poisson
# 折れ線グラフ用(ポアソン分布)のデータ
mu = 3.92
x_range = np.arange(10)
poisson_data = [poisson.pmf(x,mu) for x in x_range]
# ヒストグラム用のデータ
hist_data = pd.Series([2,2,4,6,4,5,2,3,1,2,0,4,3,3,3,3,4,2,7,2,4,3,3,3,4,3,7,5,3,1,7,6,4,6,5,2,4,7,2,2,6,2,4,5,4,5,1,3,2,3])
# グラフの作成
fig, ax1 = plt.subplots()
# 折れ線グラフの描画
ax1.plot(x_range, poisson_data)
# 2軸化
ax2 = ax1.twinx()
# ヒストグラムの描画
ax2.hist(hist_data, bins=np.arange(-0.5, 8.5, 1.0), alpha=0.4)
【実行結果】

vlines,hlines 縦線・横線の描画
縦線(垂直線)・横線(水平線)を描画します。
import matplotlib.pyplot as plt
plt.vlines(1, -5, 5, colors='blue', linestyle='dashed')
【実行結果】

import matplotlib.pyplot as plt
plt.hlines(1, -5, 5, colors='red', linestyle='dashed')
【実行結果】

imshow 配列を画像で表示
配列や画像または画像の配列データを画像で表示します。
imshow( X, extent, origin, cmap )
X | 配列 or PIL画像 or PIL画像の配列 |
extent | (オプション)画像の中心から上下左右の幅を指定 [左,右,下,上] 左右はx軸、上下はy軸の幅となる |
origin | 座標原点(0,0)の位置を指定 upper(デフォルト):左上 lower:左下 |
cmap | カラーマップを指定 |
# 画像を配列に変換して表示
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
# 画像の取得
image = Image.open("画像/rabbit.jpg")
# 画像を配列に変換
image_array = np.array(image)
plt.imshow(image_array)
【実行結果】

import matplotlib.pyplot as plt
import numpy as np
# ダミーデータ用関数の定義
def f(x, y):
return np.sin(x) + np.cos(10 + y * x)
# ダミーデータ作成
x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
# 三次元の画像表示
plt.imshow(Z, extent=[0, 5, 0, 5], origin='lower',
cmap='RdGy',aspect=0.8)
plt.colorbar()
【実行結果】
