Python中如何将图例放置在图表外部

Python中如何将图例放置在图表外部

技术背景

在使用Python进行数据可视化时,Matplotlib和Seaborn是常用的绘图库。当绘制多个系列的数据时,图例(legend)是用于标识每个数据系列的重要元素。然而,当数据系列较多或者图例内容较长时,图例可能会覆盖图表区域,影响图表的可读性。因此,将图例放置在图表外部是一种常见的需求。同时,调整图例内部文本的字体大小,也有助于在有限的空间内展示更多信息。

实现步骤

1. 使用bbox_to_anchor参数

bbox_to_anchor参数可以用来手动指定图例的位置。以下是一些示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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='$y = %ix$' % i)

# 将图例稍微移出坐标轴边界
ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

2. 调整图表大小以容纳外部图例

可以通过缩小当前图表的宽度或高度,为图例留出空间。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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='$y = %ix$' % i)

# 缩小当前坐标轴宽度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()

3. 使用plt.subplots_adjust调整子图参数

通过调整子图参数,使坐标轴在图形中占用更少的空间,从而为图例留出空间。示例代码如下:

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='$y = %ix$' % i)

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

# 调整子图参数,在图形右侧留出30%的空间
plt.subplots_adjust(right=0.7)

plt.show()

4. 使用plt.tight_layout自动调整布局

plt.tight_layout可以自动调整子图参数,使图形中的元素紧密贴合图形边缘。可以通过传递rect参数来指定子图区域的边界。示例代码如下:

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='$y = %ix$' % i)

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

# 自动调整子图参数,使子图区域适应指定的矩形框
plt.tight_layout(rect=[0, 0, 0.75, 1])

plt.show()

5. 使用fig.legend创建图形级别的图例

从Matplotlib 2.1版本开始,可以使用fig.legend创建图形级别的图例,它会自动将图例放置在图表外部。示例代码如下:

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

x = np.linspace(0, 2*np.pi)
colors = ["#7aa0c4", "#ca82e1", "#8bcd50", "#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
axes[i//2].plot(x, np.sin(x+i), color=colors[i], label="y=sin(x + {})".format(i))

fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)
plt.show()

6. 在专用子图坐标轴中放置图例

可以将图例放置在专用的子图坐标轴中。示例代码如下:

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

plt.rcParams["figure.figsize"] = 6, 2

x = np.linspace(0, 2*np.pi)
y = np.sin(x)

fig, (ax, lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4, 1]})
ax.plot(x, y, label="y=sin(x)")

h, l = ax.get_legend_handles_labels()
lax.legend(h, l, borderaxespad=0)
lax.axis("off")

plt.tight_layout()
plt.show()

核心代码

调整图例字体大小

可以通过FontProperties或直接指定fontsize来调整图例内部文本的字体大小。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('xx-small')

p1, = plt.plot([1, 2, 3], label='Line 1')
p2, = plt.plot([3, 2, 1], label='Line 2')
plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', prop=fontP)

# 或者直接指定fontsize
# plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', fontsize='xx-small')

plt.show()

防止保存图形时图例被裁剪

在保存图形时,可以使用bbox_extra_artistsbbox_inches='tight'参数来确保图例不会被裁剪。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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( [ 'Lag ' + str(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')

最佳实践

  • 优先尝试不同的位置:在调整字体大小之前,先尝试将图例放置在不同的位置,如右上角、底部等,看是否能满足需求。
  • 结合使用多种方法:可以同时使用bbox_to_anchorplt.subplots_adjustplt.tight_layout等方法,以达到最佳的布局效果。
  • 使用图形级别的图例:对于包含多个子图的图形,使用fig.legend可以更方便地将图例放置在合适的位置。

常见问题

1. 图例被裁剪

  • 解决方法:使用bbox_extra_artistsbbox_inches='tight'参数来确保图例不会被裁剪,或者使用plt.subplots_adjustplt.tight_layout调整子图参数。

2. 图例覆盖图表内容

  • 解决方法:将图例放置在图表外部,如使用bbox_to_anchor参数指定图例的位置,或者缩小图表的宽度或高度,为图例留出空间。

3. 字体大小调整后可读性差

  • 解决方法:尝试使用合适的字体大小,避免使用过小的字体。同时,可以调整图例的布局,如使用多行或多列显示。

Python中如何将图例放置在图表外部
https://119291.xyz/posts/2025-04-18.python-legend-outside-plot-guide/
作者
ww
发布于
2025年4月18日
许可协议