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)
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))
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)
plt.show()
|
防止保存图形时图例被裁剪
在保存图形时,可以使用bbox_extra_artists
和bbox_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_anchor
、plt.subplots_adjust
和plt.tight_layout
等方法,以达到最佳的布局效果。 - 使用图形级别的图例:对于包含多个子图的图形,使用
fig.legend
可以更方便地将图例放置在合适的位置。
常见问题
1. 图例被裁剪
- 解决方法:使用
bbox_extra_artists
和bbox_inches='tight'
参数来确保图例不会被裁剪,或者使用plt.subplots_adjust
或plt.tight_layout
调整子图参数。
2. 图例覆盖图表内容
- 解决方法:将图例放置在图表外部,如使用
bbox_to_anchor
参数指定图例的位置,或者缩小图表的宽度或高度,为图例留出空间。
3. 字体大小调整后可读性差
- 解决方法:尝试使用合适的字体大小,避免使用过小的字体。同时,可以调整图例的布局,如使用多行或多列显示。