如何将图例放置在绘图区域之外

如何将图例放置在绘图区域之外

技术背景

在数据可视化中,当绘制的图形包含多个元素时,图例是帮助读者理解图形的重要工具。然而,图例有时会占据绘图区域内的空间,导致图形布局不够美观,甚至遮挡数据。因此,将图例放置在绘图区域之外是一个常见的需求。Matplotlib 是 Python 中广泛使用的绘图库,提供了多种方法来实现这一目的。

实现步骤

使用 bbox_to_anchor 参数

bbox_to_anchor 是一个非常灵活的参数,用于手动指定图例的位置。可以提供一个元组来指定图例左下角的坐标,或者提供一个完整的边界框。

1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)
fig = plt.figure()
ax = plt.subplot(111)

for i in range(5):
ax.plot(x, i * x, label=f'$y = {i}x$')

ax.legend(bbox_to_anchor=(1.1, 1.05))
plt.show()

收缩绘图区域

通过收缩当前绘图区域的宽度或高度,为图例留出空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)
fig = plt.figure()
ax = plt.subplot(111)

for i in range(5):
ax.plot(x, i * x, label=f'$y = {i}x$')

# 收缩当前轴的宽度 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# 将图例放在当前轴的右侧
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.show()

使用 fig.legend

在 Matplotlib 3.7 及以后的版本中,可以直接使用 fig.legend 并指定 loc='outside right upper' 等位置。

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(layout='constrained')
x = np.linspace(-np.pi, np.pi)
ax.plot(x, x, label='$f(x) = x$')
ax.plot(x, np.sin(x), label='$f(x) = sin(x)$')
ax.plot(x, np.cos(x), label='$f(x) = cos(x)$')

fig.legend(loc='outside right upper')
plt.show()

核心代码

以下是使用 bbox_to_anchorfig.legend 的核心代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 使用 bbox_to_anchor
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)
fig = plt.figure()
ax = plt.subplot(111)

for i in range(5):
ax.plot(x, i * x, label=f'$y = {i}x$')

ax.legend(bbox_to_anchor=(1.1, 1.05))
plt.show()

# 使用 fig.legend (Matplotlib 3.7+)
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(layout='constrained')
x = np.linspace(-np.pi, np.pi)
ax.plot(x, x, label='$f(x) = x$')
ax.plot(x, np.sin(x), label='$f(x) = sin(x)$')
ax.plot(x, np.cos(x), label='$f(x) = cos(x)$')

fig.legend(loc='outside right upper')
plt.show()

最佳实践

  • 调整布局:使用 plt.tight_layout()fig.tight_layout() 自动调整子图参数,使图形元素紧密贴合图形边缘。
  • 设置透明度:如果图例无法完全放置在绘图区域之外,可以将图例设置为半透明,以减少对数据的遮挡。
1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)
x = np.arange(-5, 6)
ax.plot(x, x*x, label='y = x^2')
ax.plot(x, x*x*x, label='y = x^3')

# 使图例透明
ax.legend(loc=2, fontsize=10, fancybox=True).get_frame().set_alpha(0.5)
plt.show()

常见问题

图例被裁剪

当使用 bbox_to_anchor 将图例放置在绘图区域之外时,图例可能会被裁剪。可以使用 bbox_extra_artistsbbox_inches='tight' 来解决这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import matplotlib.pyplot as plt

# 数据
all_x = [10, 20, 30]
all_y = [[1, 3], [1.5, 2.9], [3, 2]]

# 绘图
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# 添加图例、标题和轴标签
lgd = ax.legend([f'Lag {lag}' for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')

fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')

loc='best' 不会将图例放置在绘图区域之外

loc='best' 会自动将图例放置在不与数据重叠的位置,但不会将图例放置在绘图区域之外。如果需要将图例放置在绘图区域之外,需要使用其他方法。


如何将图例放置在绘图区域之外
https://119291.xyz/posts/how-to-put-the-legend-outside-the-plot/
作者
ww
发布于
2025年5月28日
许可协议