PythonのMatplotlibでグラフを表示するときに,グラフの領域を塗りつぶしたいと思ったことはないでしょうか?
範囲を示したい場合や誤差範囲を表現したい場合などによく領域を塗りつぶして表示されています
折れ線グラフとよく似た面グラフを表示する場合もこの方法です
本記事ではMatplotlibで領域を塗りつぶしてグラフを表示するためのAxes.fill_between関数とAxes.fill_betweenx関数の使い方について説明します
積み上げ面グラフに関しては下記の記事を参考にしてください

折れ線グラフの領域を塗りつぶす (Axes.fill_between)
グラフの領域を塗りつぶして表示するにはAxes.fill_between関数を使います
- 引数
-
- x (配列) : グラフデータのx座標
- y1 (配列 or 数値) : グラフデータのy座標
- y2 (配列 or 数値) : グラフデータのy座標を指定し,y1との間が塗りつぶされます
- where (配列) : 塗りつぶす条件
- interpolate (True or False) : whereが使用され,2つの曲線が交差している場合にのみ関連します.実際の交点を計算し,この点まで塗りつぶし領域を拡張します
- step (‘pre’, ‘post’, ‘mid’) : ステップ関数
- alpha (float) : 透明度を0~1の範囲で指定
- color (color) : 塗りつぶす色を指定
- 返値
- 公式ドキュメント
今回使用するデータと折れ線グラフをまずはご説明します
下記のタブにコードとフローチャートで解説しています
import matplotlib.pyplot as plt
import numpy as np
# step1 データの作成
x = np.linspace(0, 10, 100)
y1 = 2 * np.sin(2 * x)
y2 = 4 + 2 * np.sin(2 * x)
# step2 グラフフレームの作成
fig, ax = plt.subplots()
# step3 グラフの描画
ax.plot(x, y1, label=r'$y1 = 2sin(2x)$')
ax.plot(x, y2, label=r'$y2 = y1+4$')
ax.set_title(r'plot y1, y2')
ax.set_xlabel('X label')
ax.set_ylabel('Y label')
ax.set_ylim(-3, 8)
ax.legend()
plt.show()

折れ線グラフと指定した数値の範囲を塗りつぶす
Axes.fill_between関数はAxes.plot関数による折れ線グラフの描画方法と同じように使えます
xとyのみを指定すると,yと0の間が塗りつぶされます
# step3 グラフの描画
# y1から0の範囲を塗りつぶしたグラフ
ax.fill_between(x, y1, label=r'$y1 = 2sin(2x)$')
plt.show()

次は,yの次の引数に数値を指定して任意の範囲を塗りつぶします
yと1の間塗りつぶします
# y1から1の範囲を塗りつぶしたグラフ
ax.fill_between(x, y1, 1, label=r'$y1 = 2sin(2x)$')
plt.show()

2つの折れ線グラフの間を塗りつぶす
Axes.fill_between関数の引数を,x, y1, y2の順で指定するだけで折れ線グラフの間が塗りつぶされます
# step3 グラフの描画
# y1からy2の範囲を塗りつぶしたグラフ
ax.fill_between(x, y1, y2, label=r'$y1 = 2sin(2x), y2 = y1+4$')
plt.show()

折れ線グラフの誤差範囲を塗りつぶす (alpha)
折れ線グラフの誤差範囲を塗りつぶす場合は,Axes.fill_between関数の3番目の引数を配列にします
また,alphaを0〜1で入力することで透明度を指定できます
下記のタブにコードとフローチャートで解説しています
# step1 データの作成
x = np.linspace(0, 10, 11)
y = [3.9, 4.4, 10.8, 10.3, 11.2, 13.1, 14.1, 9.9, 13.9, 15.1, 12.5]
# step2 予測線と誤差範囲の推定
a, b = np.polyfit(x, y, deg=1)
y_est = a * x + b
y_err = x.std() * np.sqrt(1/len(x) +
(x - x.mean())**2 / np.sum((x - x.mean())**2))
# step3 グラフフレームの作成
fig, ax = plt.subplots()
# step4 グラフの描画
# 予測線
ax.plot(x, y_est)
# 予測線の信頼区間
ax.fill_between(x, y_est - y_err, y_est + y_err, alpha=0.2)
# 実際のデータ
ax.scatter(x, y)
ax.set_title(r'Confidence bands')
plt.show()

塗りつぶす範囲を条件で指定する (where, facecolor)
引数にwhereを用いて条件指定することで,塗りつぶす範囲をより細かく指定することができます
今回使用するデータと折れ線グラフをまずはご説明します
下記のタブにコードとフローチャートで解説しています
# step1 データの作成
x = np.linspace(0, 10, 100)
y1 = 2 * np.sin(2 * x)
y2 = 2 * np.cos(2 * x)
# step2 グラフフレームの作成
fig, ax = plt.subplots()
# step3 グラフの描画
ax.plot(x, y1)
ax.plot(x, y2)
plt.show()

yの数値が大きい時だけ塗りつぶす (where)
上記のグラフを見るとわかるように,y1とy2は比較すると数値の大小が入れ替わります
そこで,y2がy1よりも大きい時だけ塗りつぶしをしました
# step3 グラフの描画
# y2の値がy1よりも大きい場合に塗りつぶし
ax.fill_between(x, y1, y2, where=y2 >= y1)
plt.show()

次に,y2がy1よりも小さい時だけ塗りつぶしをしました
# step3 グラフの描画
# y2の値がy1よりも小さい場合に塗りつぶし
ax.fill_between(x, y1, y2, where=y2 <= y1)
plt.show()

条件ごとに塗りつぶす色を変える (color)
Axes.fill_between関数の引数にwhereとfacecolorの2つを指定すると条件ごとに色を変えることができます
y1とy2の大小関係が入れ替わるごとに色を変更します
# step3 グラフの描画
# facecolorで塗りつぶす色を指定
ax.fill_between(x, y1, y2, where=y2 >= y1, color='C0')
ax.fill_between(x, y1, y2, where=y2 <= y1, color='C1')
plt.show()

交差点まで塗りつぶす領域を拡大する (interpolation)
交差点を含むx配列はうまく塗りつぶされていない場合があります
interpolateをTrueに設定すると,実際の交点が計算され,交差点まで塗りつぶし領域が拡大されます
下記のタブにコードとフローチャートで解説しています
- (x, y1)と(x, y2)のマーク付き折れ線グラフ
- y2の値がy1よりも大きい場合に塗りつぶしたグラフ
- y2の値がy1よりも小さい場合に塗りつぶしたグラフ
# step1 データの作成
x = np.array([0, 1, 2, 3])
y1 = np.array([0.8, 0.8, 0.2, 0.2])
y2 = np.array([0, 0, 1, 1])
# step2 グラフフレームの作成
fig, ax = plt.subplots()
# step3 グラフの描画
ax.plot(x, y1, 'o--')
ax.plot(x, y2, 'o--')
ax.fill_between(x, y1, y2, where=(y1 > y2), color='C0', alpha=0.3,
interpolate=True)
ax.fill_between(x, y1, y2, where=(y1 <= y2), color='C1', alpha=0.3,
interpolate=True)
ax.set_title('interpolation=True')
plt.show()


折れ線グラフの領域をx方向に塗りつぶす (Axes.fill_betweenx)
Axes.fill_betweenx関数はx方向に塗りつぶすことができます
- 引数
-
- y (配列) : グラフデータのy座標
- x1 (配列 or 数値) : グラフデータのx座標
- x2 (配列 or 数値) : グラフデータのx座標を指定し,x1との間が塗りつぶされます
- where (配列) : 塗りつぶす条件
- interpolate (True or False) : whereが使用され,2つの曲線が交差している場合にのみ関連します.実際の交点を計算し,この点まで塗りつぶし領域を拡張します
- step (‘pre’, ‘post’, ‘mid’) : ステップ関数
- alpha (float) : 透明度を0~1の範囲で指定
- color (color) : 塗りつぶす色を指定
- 返値
- 公式ドキュメント
下記のタブにコードとフローチャートで解説しています
# step1 データの作成
y = np.linspace(0, 10, 100)
x1 = 2 * np.sin(2 * y)
x2 = 4 + 2 * np.sin(2 * y)
# step2 グラフフレームの作成
fig, ax = plt.subplots()
# step3 グラフの描画
ax.plot(x1, y, '--', label=r'$x1 = 2sin(2y)$')
ax.plot(x2, y, '--', label=r'$x1 = x2+4$')
ax.set_title(r'plot x1 and x2')
ax.set_xlim(-3, 10)
ax.legend()
plt.show()

上記のx1, x2の折れ線グラフの間をx方向に塗りつぶします
# step3 グラフの描画
ax.fill_betweenx(y, x1, x2, alpha=0.5)
plt.show()

参考文献
折れ線グラフの塗りつぶし
Axes.fill_between関数
x方向の折れ線グラフの塗りつぶし
Axes.fill_betweenx関数
お疲れさまでした
コメント