概要
matplotlib でグラフに凡例 (legend
) を表示する方法について解説します。
legend
凡例を表示する
何も引数を指定しない場合、折れ線などの描画物を作成した際に label
引数で指定したラベルが凡例に表示されます。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend()
plt.show()
凡例のラベルを指定する
折れ線などの描画物を作成した際に label
引数で指定したラベルとは別のラベルを表示したい場合は、ラベルのリストを指定します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(["A", "B"])
plt.show()
指定した Artist に凡例をつける
折れ線などの描画物を作成した際の返り値である Artist とラベルをそれぞれリストで渡すことでも凡例を作成できます。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(facecolor="w")
(line1,) = ax.plot(x, y1, label="sin")
(line2,) = ax.plot(x, y2, label="cos")
ax.legend([line1, line2], ["A", "B"])
plt.show()
凡例の位置を指定する
bbox_to_anchor=(x, y, width, height)
と loc
で指定した場合
bbox_to_anchor
は、Axes 座標系 (左下が (0, 0)
、右上が (1, 1)
) で、凡例を配置する際の基準となる矩形の位置及び大きさになります。この矩形内の loc
で指定した場所に凡例が配置されます。borderaxespad
で矩形と凡例の間のパディングをフォントサイズ単位で指定できます。
loc
は bbox_to_anchor
内の相対位置で指定します。(わかりやすいように bbox_to_anchor
を赤で可視化しています)
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
locs = [
"upper left",
"upper right",
"lower left",
"lower right",
"center left",
"center right",
"upper center",
"lower center",
"center",
"best",
"right",
]
fig = plt.figure(figsize=(8, 15), facecolor="w")
plt.subplots_adjust(hspace=0.5)
for i, loc in enumerate(locs, 1):
ax = fig.add_subplot(6, 2, i)
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.set_title(f"loc='{loc}'")
ax.legend(loc=loc, bbox_to_anchor=(0.5, 0, 0.5, 1))
# わかりやすいように bbox_to_anchor を可視化する。
rect = plt.Rectangle(
(0.5, 0),
0.5,
1,
edgecolor="r",
facecolor="none",
clip_on=False,
lw=2,
zorder=10,
)
rect.set_transform(ax.transAxes) # axes 座標系に指定する。
ax.add_patch(rect)
plt.show()
loc=(x, y)
を指定した場合
loc=(x, y)
と指定した場合、Axes 座標系 (左下が (0, 0)、右上が (1, 1)) で、凡例の左下がこの位置にくるように配置されます。このとき、bbox_to_anchor
、borderaxespad
は無視されます。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(loc=(0.1, 0.1))
plt.show()
bbox_to_anchor=(x, y)
と loc
で指定した場合
bbox_to_anchor=(x, y)
と指定した場合、Axes 座標系 (左下が (0, 0)、右上が (1, 1)) で、この位置に凡例を配置する際の基準となる点を作成します。凡例は loc
で指定した位置がこの基準点にくるように配置されます。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Circle
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(8, 15), facecolor="w")
plt.subplots_adjust(hspace=0.5)
locs = [
"upper left",
"upper right",
"lower left",
"lower right",
"center left",
"center right",
"upper center",
"lower center",
"center",
"best",
"right",
]
cols = 2
rows = np.ceil(len(locs) / cols)
for i, loc in enumerate(locs, 1):
ax = fig.add_subplot(rows, cols, i)
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.set_title(f"loc='{loc}'")
ax.legend(loc=loc, bbox_to_anchor=(0.5, 0.2), borderaxespad=0)
# わかりやすいように bbox_to_anchor を可視化する。
circle = Circle((0.5, 0.2), 0.02, facecolor="r", zorder=10, clip_on=False)
circle.set_transform(ax.transAxes) # axes 座標系
ax.add_patch(circle)
plt.show()
凡例の列数を指定する
ncol
で凡例の列数を指定できます。(デフォルトは1)
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(ncol=2)
plt.show()
点付きの折れ線グラフの場合
凡例の点の数を指定する
点付きの折れ線グラフの場合、numpoints
で凡例の点の数を指定できます。
デフォルトは rcParams["legend.numpoints"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([1, 2, 3], 1):
ax = fig.add_subplot(3, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"numpoints={param}")
ax.legend(numpoints=param)
plt.show()
凡例の点の大きさを指定する
点付きの折れ線グラフの場合、markerscale
で凡例の点の大きさを指定できます。
デフォルトは rcParams["legend.markerscale"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([1, 2, 3], 1):
ax = fig.add_subplot(3, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"markerscale={param}")
ax.legend(markerscale=param)
plt.show()
マーカーをラベルの前に持ってくるかどうかを指定する
markerfirst=True
の場合、左からマーカー、ラベルの順に配置し (デフォルト)、markerfirst=False
の場合、左からラベル、マーカーの順に配置します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([True, False], 1):
ax = fig.add_subplot(2, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"markerfirst={param}")
ax.legend(markerfirst=param)
plt.show()
凡例の枠を指定する
凡例の枠を付けるかどうかを指定する
frameon
で凡例の枠を付けるかどうかを指定できます。
デフォルトは rcParams["legend.frameon"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([True, False], 1):
ax = fig.add_subplot(2, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"frameon={param}")
ax.legend(frameon=param)
plt.show()
凡例の枠の角を丸めるかどうかを指定する
fancybox
で凡例の枠の角を丸めるかどうかを指定できます。
デフォルトは rcParams["legend.fancybox"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([True, False], 1):
ax = fig.add_subplot(2, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"fancybox={param}")
ax.legend(fancybox=param)
plt.show()
凡例の枠に影をつけるかどうかを指定する
shadow
で凡例の枠に影をつけるかどうかを指定できます。
デフォルトは rcParams["legend.shadow"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([True, False], 1):
ax = fig.add_subplot(2, 1, i)
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"shadow={param}")
ax.legend(shadow=param)
plt.show()
凡例を透過するかどうかを指定する
framealpha
で凡例の透過度を指定できます。
デフォルトは rcParams["legend.framealpha"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate([0.3, 0.5, 1], 1):
ax = fig.add_subplot(3, 1, i, facecolor="lightgray")
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title("framealpha={}".format(param))
ax.legend(framealpha=param)
plt.show()
凡例の色を指定する
facecolor
で凡例の色を指定できます。
デフォルトは rcParams["legend.facecolor"]
の値を使用します。facecolor="inherit"
を指定した場合、rcParams["axes.facecolor"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate(["pink", "lightgreen", "lightblue"], 1):
ax = fig.add_subplot(3, 1, i, facecolor="lightgray")
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"facecolor='{param}'")
ax.legend(facecolor=param)
plt.show()
凡例の枠の色を指定する
edgecolor
で凡例の色を指定できます。デフォルトは rcParams["legend.edgecolor"]
の値を使用します。edgecolor="inherit"
を指定した場合、rcParams["axes.edgecolor"]
の値を使用します。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(5, 8), facecolor="w")
for i, param in enumerate(["pink", "lightgreen", "lightblue"], 1):
ax = fig.add_subplot(3, 1, i, facecolor="lightgray")
ax.plot(x, y1, "ro-", ms=3, label="sin")
ax.plot(x, y2, "bo-", ms=3, label="cos")
ax.set_title(f"edgecolor='{param}'")
ax.legend(edgecolor=param)
plt.show()
凡例の枠を Axes の横幅に広げる
mode="expand"
を指定した場合、凡例を Axes の横幅に広げます。bbox_to_anchor
を指定している場合、凡例の広がる幅はこの矩形内になります。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(mode="expand", loc="lower center", bbox_to_anchor=(0.5, 0, 0.5, 1))
plt.show()
凡例にタイトルをつける
title
で凡例にタイトルを指定できます。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(title="title", title_fontsize=12)
plt.show()
凡例内のラベル、マーカーの配置を指定する
引数 | デフォルト値 | 単位 | |
---|---|---|---|
borderpad | 凡例の枠とラベルのスペース | rcParams["legend.borderpad"] |
|
labelspacing | ラベル間のスペース | rcParams["legend.labelspacing"] |
フォントサイズ |
handlelength | ハンドルの長さ | rcParams["legend.handlelength"] |
フォントサイズ |
handletextpad | ハンドルとラベルのスペース | rcParams["legend.handletextpad"] |
|
columnspacing | 列が2列以上のとき、列の間のスペース | rcParams["legend.columnspacing"] |
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(borderpad=1, labelspacing=1, handlelength=4, handletextpad=1)
plt.show()
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(5, 3), facecolor="w")
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(ncol=2, columnspacing=1)
plt.show()
コメント