📈

Matplotlib で複数の図に一つの凡例を描画する

2023/02/27に公開

matplotlibfigure.add_subplot を使って複数の図を描く,という状況を考えます.

こういう状況は,例えば手法 A と手法 B を複数のデータ上で比較するといった場合に起こります.

ここでは,簡単のために次のような例を考えます.


import matplotlib.pyplot as plt
import numpy as np

N_ROW, N_COL = 1, 2

x = np.linspace(0, 10, 100)


# 幅6,高さ4の図2つ分の描画領域を描く
fig = plt.figure(figsize=(12, 4))

# 1つ目のグラフを描画
ax = fig.add_subplot(N_ROW, N_COL, 1)
ax.plot(x, np.sin(x), label='A', color='orangered')
ax.plot(x, np.cos(x), label='B', color='aqua')
ax.set_ylim(-2.1, 2.1)
ax.set_title('DEMO 1')
ax.legend(loc='upper right')


# 2つ目のグラフを描画
ax = fig.add_subplot(N_ROW, N_COL, 2)
ax.plot(x, 2.0 * np.sin(x), label='A', color='orangered')
ax.plot(x, 2.0 * np.cos(x), label='B', color='aqua')
ax.set_ylim(-2.1, 2.1)
ax.set_title('DEMO 2')
ax.legend(loc='upper right')

plt.show()

この例ではどちらも AB というラベルがついており,冗長に見えます.

このラベルを一つにまとめるには次のようにすれば良いです.
図を2つから3つに増やし,3つ目の領域に凡例を描きます.

N_ROW, N_COL = 1, 3

x = np.linspace(0, 10, 100)


# 幅6,高さ4の図3つ分の描画領域を描く
# 幅が 3つ分になったので,図の比を変えないために18にする.
fig = plt.figure(figsize=(18, 4))

# 1つ目のグラフを描画
ax = fig.add_subplot(N_ROW, N_COL, 1)
ax.plot(x, np.sin(x), label='A', color='orangered')
ax.plot(x, np.cos(x), label='B', color='aqua')
ax.set_ylim(-2.1, 2.1)
ax.set_title('DEMO 1')



# 2つ目のグラフを描画
ax = fig.add_subplot(N_ROW, N_COL, 2)
ax.plot(x, 2.0 * np.sin(x), label='A', color='orangered')
ax.plot(x, 2.0 * np.cos(x), label='B', color='aqua')
ax.set_ylim(-2.1, 2.1)
ax.set_title('DEMO 2')

# 2つ目のグラフの凡例を取得.
# どちらのグラフから凡例を取っても良い.
handles, labels = ax.get_legend_handles_labels()

# 凡例を描画する領域を ax とする
ax = fig.add_subplot(N_ROW, N_COL, 3)

# 凡例を描くための場所なので,軸を消す
ax.axis('off')
ax.legend(handles=handles, loc='center', fontsize=16)

plt.show()


Zenn 上では図が小さく見えるかもしれませんが,実際には同じ大きさです.

もちろん,bbox_to_anchor を使って位置を指定しても大丈夫です.

Discussion