Matplotlib legend() 函数
legend() 用于在图表中添加图例,帮助读者识别每条曲线或每组数据对应的含义。
函数定义
matplotlib.pyplot.legend(*args, **kwargs) Axes.legend(*args, **kwargs) Figure.legend(*args, **kwargs)
常用参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| loc | str 或 int | 图例位置:'best'(自动)、'upper right'、'upper left'、'lower left'、'lower right'、'right'、'center left'、'center right'、'lower center'、'upper center'、'center'、'outside'(外侧) |
| bbox_to_anchor | tuple | 图例锚点坐标,配合 loc 精确定位。如 (1.05, 1) 将图例放在 Axes 外侧右上角 |
| ncol | int | 图例列数,默认 1。多条目时分多列显示 |
| fontsize | int 或 str | 图例字体大小,如 10、'small'、'large' |
| frameon | bool | 是否显示图例边框,默认 True |
| shadow | bool | 是否添加阴影效果 |
| title | str | 图例的标题 |
| facecolor | color | 图例背景色 |
| edgecolor | color | 图例边框颜色 |
| fancybox | bool | 是否使用圆角边框,默认 True |
| markerscale | float | 图例中标记相对于原始标记的缩放比例 |
| handlelength | float | 图例中线条的长度 |
图例只显示设置了
label参数的 Artist。常见做法是在 plot()、scatter()、bar() 等绘图函数中直接指定 label,然后调用 legend()。
使用示例
示例 1:基本图例
实例
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(layout='constrained')
# 每条曲线的 label 会自动进入图例
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.plot(x, np.sin(x) * np.exp(-x/3), label='damped sin(x)')
ax.legend(loc='upper right') # 自动收集所有 label
ax.set_title('Basic Legend')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(layout='constrained')
# 每条曲线的 label 会自动进入图例
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.plot(x, np.sin(x) * np.exp(-x/3), label='damped sin(x)')
ax.legend(loc='upper right') # 自动收集所有 label
ax.set_title('Basic Legend')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
示例 2:图例在图表外侧 + 多列
实例
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 绘制多条曲线
for i in range(6):
ax.plot(x, np.sin(x + i * 0.5), label=f'sin(x + {i*0.5:.1f})')
# 图例放在 Axes 外侧,分两列显示
ax.legend(loc='upper left',
bbox_to_anchor=(1.02, 1), # 外侧右上角
ncol=2, # 分两列
title='Phase Shift',
frameon=True,
fancybox=True,
shadow=True)
ax.set_title('Legend Outside the Plot (ncol=2)')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 绘制多条曲线
for i in range(6):
ax.plot(x, np.sin(x + i * 0.5), label=f'sin(x + {i*0.5:.1f})')
# 图例放在 Axes 外侧,分两列显示
ax.legend(loc='upper left',
bbox_to_anchor=(1.02, 1), # 外侧右上角
ncol=2, # 分两列
title='Phase Shift',
frameon=True,
fancybox=True,
shadow=True)
ax.set_title('Legend Outside the Plot (ncol=2)')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
示例 3:自定义图例条目
实例
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(layout='constrained')
ax.plot(x, np.sin(x), 'b-', linewidth=2)
ax.plot(x, np.cos(x), 'r--', linewidth=2)
# 手动指定图例条目(不与绘图 label 关联)
blue_line = mpatches.Patch(color='blue', label='Sine Wave')
red_line = mpatches.Patch(color='red', label='Cosine Wave')
ax.legend(handles=[blue_line, red_line],
loc='upper right',
fontsize=11)
ax.set_title('Custom Legend Handles')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
import matplotlib.patches as mpatches
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(layout='constrained')
ax.plot(x, np.sin(x), 'b-', linewidth=2)
ax.plot(x, np.cos(x), 'r--', linewidth=2)
# 手动指定图例条目(不与绘图 label 关联)
blue_line = mpatches.Patch(color='blue', label='Sine Wave')
red_line = mpatches.Patch(color='red', label='Cosine Wave')
ax.legend(handles=[blue_line, red_line],
loc='upper right',
fontsize=11)
ax.set_title('Custom Legend Handles')
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
plt.show()
示例 4:图例位置代码速查
实例
import matplotlib.pyplot as plt
# 展示所有 loc 代码对应的位置
locations = [
'upper left', 'upper right', 'lower left', 'lower right',
'center left', 'center right', 'lower center', 'upper center',
'center'
]
fig, axes = plt.subplots(3, 3, figsize=(10, 8),
layout='constrained')
axes = axes.flatten()
for ax, loc in zip(axes, locations):
ax.plot([0, 1], [0, 1], 'b-', label='Line A')
ax.plot([0, 1], [1, 0], 'r--', label='Line B')
ax.legend(loc=loc, fontsize=8, title=f'loc="{loc}"')
ax.set_xticks([])
ax.set_yticks([])
fig.suptitle('All legend() Locations', fontsize=14)
plt.show()
# 展示所有 loc 代码对应的位置
locations = [
'upper left', 'upper right', 'lower left', 'lower right',
'center left', 'center right', 'lower center', 'upper center',
'center'
]
fig, axes = plt.subplots(3, 3, figsize=(10, 8),
layout='constrained')
axes = axes.flatten()
for ax, loc in zip(axes, locations):
ax.plot([0, 1], [0, 1], 'b-', label='Line A')
ax.plot([0, 1], [1, 0], 'r--', label='Line B')
ax.legend(loc=loc, fontsize=8, title=f'loc="{loc}"')
ax.set_xticks([])
ax.set_yticks([])
fig.suptitle('All legend() Locations', fontsize=14)
plt.show()
常见问题
图例不显示?
检查绘图函数是否设置了 label 参数。
确认调用了 legend() 函数。
如果某些 Artist 不需要出现在图例中,将 label 设为空字符串或 '_nolegend_'。
如何局部修改图例中的线条样式?
通过 legend.get_lines() 获取图例中的线条对象并修改其属性,或使用 handler_map 参数。

Matplotlib 参考文档