動機
以下のようなcolorbarを共有したグラフを作成したいものとします.
結論
以下のようなコードを利用します.
contourfでcolorbarを生成して最終的にそれをfigに加える形で再現します.
注意点としては,colorbarのスケールが各々異なる場合であっても最終的に表示されるcolorbarはfor文の最後にplotされたものに準拠することです.
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["font.size"] = 14
plt.rcParams['mathtext.fontset'] = 'stix' # The setting of math font
fig, axes = plt.subplots(
nrows=2,
ncols=2,
sharex=True,
sharey=True,
)
dx = np.linspace(-1, 1, 20)
X, Y = np.meshgrid(dx, dx)
level = np.linspace(0, 1, 21)
for row in range(2):
for col in range(2):
Z = np.random.random(X.shape)
### ここから開始!!!
### ポイント1: colorbarの情報を変数として保持する
cb = axes[row][col].contourf(X, Y, Z, level)
### ポイント2: colorbarをsubplotsに新しい軸として加える
### ポイント3: padはcolorbarの位置調整に利用する
cbar = fig.colorbar(cb, ax=axes.ravel().tolist(), pad=0.025)
### ポイント4: colorbarのタイトルは以下のように加える
### ポイント5: colorbarのタイトルの位置はx, yで調整可能
cbar.ax.set_title("$f(x, y)$", y=1.01)
# cbar.set_ticks([]) # <=== colorbarの目盛りとその数値が不要なら使う
plt.show()
応用例
実は等高線以外の可視化でもcolorbarを入れることができます.
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
dx = np.linspace(0, 1, 21)
level = np.linspace(0, 1, 11)
# colorbarを生成するためにダミーとしてzerosを利用したcontourfを呼ぶ
zeros = [[0, 0], [0, 0]]
cm = plt.get_cmap("jet")
cb = ax.contourf(zeros, zeros, zeros, level, cmap=cm)
for i, a in enumerate(level):
ax.plot(dx, a * dx, color=cm(i / level.size))
# colorbarを加える
cbar = fig.colorbar(cb)
# colorbarを編集する
cbar.ax.set_title("Slope", y=1.01)
labels = [""] * 100
labels[10], labels[-10] = "Mild $\Longleftarrow$", "$\Longrightarrow$ Steep"
cbar.set_ticks(np.arange(len(labels)) / (len(labels) - 1))
cbar.set_ticklabels(labels)
cbar.ax.set_yticklabels(cbar.ax.get_yticklabels(), rotation=90, va="center")
# tick目盛りを削除
cbar.ax.tick_params(size=0)
plt.show()