Matplotlib 图例字体大小设置:全面指南
参考:How to set font size of Matplotlib axis Legend
Matplotlib 是 Python 中最流行的数据可视化库之一,它提供了丰富的绘图功能。在数据可视化中,图例(Legend)是一个重要的组成部分,它帮助读者理解图表中不同元素的含义。本文将详细介绍如何在 Matplotlib 中设置图例的字体大小,以及相关的技巧和最佳实践。
1. 图例的基本概念
在深入探讨字体大小设置之前,我们先来了解一下 Matplotlib 中图例的基本概念。
图例通常包含以下几个部分:
– 图例框:包含所有图例元素的边框
– 图例标记:用于表示数据系列的符号或线条
– 图例标签:对应于每个数据系列的文本说明
下面是一个简单的示例,展示了如何创建一个包含图例的基本图表:
import matplotlib.pyplot as plt
# 创建数据
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
# 绘制图表
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
# 添加图例
plt.legend()
# 设置标题
plt.title('Basic Plot with Legend - how2matplotlib.com')
# 显示图表
plt.show()
Output:
在这个例子中,我们使用 plt.legend()
函数添加了一个默认的图例。接下来,我们将探讨如何自定义图例的字体大小。
2. 使用 fontsize
参数设置图例字体大小
设置图例字体大小的最直接方法是在调用 legend()
函数时使用 fontsize
参数。这个参数可以接受数字值(以磅为单位)或预定义的字符串值(如 ‘small’、’medium’、’large’ 等)。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
# 使用数字值设置字体大小
plt.legend(fontsize=14)
plt.title('Legend with Custom Font Size - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们将图例的字体大小设置为 14 磅。你可以根据需要调整这个值。
如果你更喜欢使用预定义的字符串值,可以这样做:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
# 使用预定义的字符串值设置字体大小
plt.legend(fontsize='large')
plt.title('Legend with Predefined Font Size - how2matplotlib.com')
plt.show()
Output:
这里,我们使用 ‘large’ 作为字体大小的值。Matplotlib 支持的预定义字符串值包括:’xx-small’、’x-small’、’small’、’medium’、’large’、’x-large’ 和 ‘xx-large’。
3. 使用 prop
参数设置图例字体属性
如果你需要更精细的控制,可以使用 prop
参数来设置图例的字体属性。这个参数接受一个字典,可以同时指定多个字体属性,包括字体大小、字体家族、字体样式等。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
# 使用 prop 参数设置字体属性
font_props = {'family': 'serif', 'size': 12, 'style': 'italic'}
plt.legend(prop=font_props)
plt.title('Legend with Custom Font Properties - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们不仅设置了字体大小为 12 磅,还指定了字体家族为 serif,样式为斜体。
4. 使用 rcParams
全局设置图例字体大小
如果你想在整个脚本或笔记本中统一设置图例的字体大小,可以使用 Matplotlib 的 rcParams
配置系统。这种方法可以避免在每个图表中重复设置字体大小。
import matplotlib.pyplot as plt
# 全局设置图例字体大小
plt.rcParams['legend.fontsize'] = 14
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
plt.legend()
plt.title('Legend with Global Font Size Setting - how2matplotlib.com')
plt.show()
Output:
这个设置会影响之后创建的所有图表的图例字体大小。如果你只想临时更改设置,可以使用 with
语句:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
with plt.rc_context({'legend.fontsize': 16}):
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
plt.legend()
plt.title('Legend with Temporary Font Size Setting - how2matplotlib.com')
plt.show()
Output:
这种方法只会在 with
语句块内影响图例字体大小,不会改变全局设置。
5. 为不同的图例项设置不同的字体大小
有时,你可能需要为图例中的不同项设置不同的字体大小。这可以通过创建自定义的图例对象来实现。
import matplotlib.pyplot as plt
from matplotlib.legend import Legend
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots()
line1 = ax.plot(x, y1, label='Series 1')[0]
line2 = ax.plot(x, y2, label='Series 2')[0]
# 创建自定义图例
legend1 = Legend(ax, [line1], ['Series 1'], loc='upper left', fontsize=12)
legend2 = Legend(ax, [line2], ['Series 2'], loc='lower right', fontsize=16)
# 添加图例到轴对象
ax.add_artist(legend1)
ax.add_artist(legend2)
plt.title('Legend with Different Font Sizes - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们为两个数据系列创建了两个独立的图例,并分别设置了不同的字体大小和位置。
6. 使用 Text
对象设置图例字体大小
对于更高级的自定义需求,你可以直接操作图例中的 Text
对象来设置字体大小。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots()
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
legend = ax.legend()
# 遍历图例中的文本对象并设置字体大小
for text in legend.get_texts():
text.set_fontsize(14)
plt.title('Legend with Font Size Set via Text Objects - how2matplotlib.com')
plt.show()
Output:
这种方法给予你更大的灵活性,因为你可以单独控制每个图例项的字体大小。
7. 根据图表大小动态调整图例字体大小
在某些情况下,你可能希望图例的字体大小能够根据图表的大小自动调整。这可以通过计算图表大小并相应地设置字体大小来实现。
import matplotlib.pyplot as plt
def set_legend_fontsize(fig, ax, base_size=12):
# 获取图表大小
fig_width, fig_height = fig.get_size_inches()
# 计算图表面积
fig_area = fig_width * fig_height
# 根据图表面积调整字体大小
fontsize = base_size * (fig_area / 50) # 50 是一个任意选择的基准面积
# 设置图例字体大小
ax.legend(fontsize=fontsize)
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
set_legend_fontsize(fig, ax)
plt.title('Legend with Dynamic Font Size - how2matplotlib.com')
plt.show()
Output:
这个例子定义了一个函数 set_legend_fontsize
,它根据图表的面积来计算适当的字体大小。你可以根据需要调整计算公式。
8. 使用样式表设置图例字体大小
Matplotlib 提供了样式表功能,允许你预定义一组样式设置,包括图例字体大小。这对于保持多个图表的一致性非常有用。
import matplotlib.pyplot as plt
# 创建自定义样式表
plt.style.use({
'legend.fontsize': 14,
'figure.figsize': (8, 6),
'axes.labelsize': 12,
'axes.titlesize': 16
})
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
plt.legend()
plt.title('Legend with Font Size Set via Style Sheet - how2matplotlib.com')
plt.show()
Output:
这个例子创建了一个自定义样式表,其中包含图例字体大小的设置。你也可以将这些设置保存在一个 .mplstyle
文件中,然后使用 plt.style.use('your_style.mplstyle')
来应用它。
9. 在子图中设置图例字体大小
当你的图表包含多个子图时,你可能需要为每个子图单独设置图例字体大小。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.plot(x, y1, label='Series 1')
ax1.plot(x, y2, label='Series 2')
ax1.legend(fontsize=10)
ax1.set_title('Subplot 1 - how2matplotlib.com')
ax2.plot(x, y2, label='Series 2')
ax2.plot(x, y1, label='Series 1')
ax2.legend(fontsize=14)
ax2.set_title('Subplot 2 - how2matplotlib.com')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们创建了两个子图,并为每个子图的图例设置了不同的字体大小。
10. 使用 bbox_to_anchor
调整图例位置和大小
有时,你可能需要精确控制图例的位置,同时调整其大小以适应更大的字体。bbox_to_anchor
参数可以帮助你实现这一点。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
# 使用 bbox_to_anchor 设置图例位置和大小
ax.legend(fontsize=16, bbox_to_anchor=(1.05, 1), loc='upper left')
plt.title('Legend with Custom Position and Size - how2matplotlib.com')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们将图例放置在图表的右上角外侧,并增加了字体大小。bbox_to_anchor
参数指定了图例框的锚点位置,loc
参数指定了图例相对于锚点的对齐方式。
11. 使用 columnspacing
和 handlelength
调整图例布局
当你增加图例的字体大小时,可能需要调整图例的其他方面以保持良好的视觉效果。columnspacing
和 handlelength
参数可以帮助你调整图例的布局。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
y3 = [3, 5, 7, 9, 11]
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
ax.plot(x, y3, label='Series 3')
ax.legend(fontsize=14, ncol=3, columnspacing=1.5, handlelength=1.5)
plt.title('Legend with Adjusted Layout - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们使用 ncol
参数将图例分为三列,columnspacing
调整列间距,handlelength
调整图例标记的长度。这些调整有助于在增加字体大小时保持图例的整体平衡。
12. 使用 labelspacing
调整图例项之间的间距
当你增加图例字体大小时,可能还需要调整图例项之间的垂直间距。labelspacing
参数可以帮助你实现这一点。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
y3 = [3, 5, 7, 9, 11]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
ax.plot(x, y3, label='Series 3')
ax.legend(fontsize=16, labelspacing=1.2)
plt.title('Legend with Adjusted Label Spacing - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们将 labelspacing
设置为 1.2,这会增加图例项之间的垂直间距,使得较大的字体看起来更加舒适。
13. 使用 markerscale
调整图例标记大小
当你增加图例字体大小时,可能还需要调整图例中的标记大小以保持视觉平衡。markerscale
参数可以帮助你实现这一点。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.scatter(x, y1, label='Series 1', s=100)
ax.scatter(x, y2, label='Series 2', s=100)
ax.legend(fontsize=16, markerscale=1.5)
plt.title('Legend with Adjusted Marker Scale - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们使用 markerscale=1.5
将图例中的标记大小增加到原来的 1.5 倍,以匹配增大的字体大小。
14. 使用 frameon
和 edgecolor
调整图例框
当你调整图例字体大小时,可能还想调整图例框的外观。frameon
参数控制是否显示图例框,而 edgecolor
可以设置框的颜色。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
ax.legend(fontsize=14, frameon=True, edgecolor='red', facecolor='lightgray')
plt.title('Legend with Custom Frame - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们启用了图例框(frameon=True
),设置了红色的边框(edgecolor='red'
),并给图例框添加了浅灰色的背景(facecolor='lightgray'
)。
15. 使用 handler_map
自定义图例项的外观
对于更高级的自定义需求,你可以使用 handler_map
来完全控制图例项的外观,包括字体大小。
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
class CustomHandler(HandlerLine2D):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
line, = super().create_artists(legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans)
line.set_markeredgewidth(3)
line.set_markersize(10)
return [line]
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
line1, = ax.plot(x, y1, label='Series 1', marker='o')
line2, = ax.plot(x, y2, label='Series 2', marker='s')
handler_map = {line1: CustomHandler(), line2: CustomHandler()}
ax.legend(fontsize=14, handler_map=handler_map)
plt.title('Legend with Custom Handlers - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们创建了一个自定义的 HandlerLine2D
子类,它可以调整图例中线条的标记大小和边缘宽度。这种方法给予你对图例项外观的完全控制。
16. 使用 bbox_extra_artists
确保图例不被裁剪
当你增加图例字体大小时,可能会发现图例被部分裁剪。使用 bbox_extra_artists
参数可以确保图例完全显示。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
legend = ax.legend(fontsize=16, bbox_to_anchor=(1.05, 1), loc='upper left')
plt.title('Legend with bbox_extra_artists - how2matplotlib.com')
plt.tight_layout()
fig.savefig('legend_plot.png', bbox_extra_artists=[legend], bbox_inches='tight')
plt.show()
Output:
在这个例子中,我们将图例放置在图表外部,并在保存图表时使用 bbox_extra_artists
参数确保图例被完整保存。
17. 使用 get_legend_handles_labels()
自定义图例顺序和内容
有时,你可能想要更改图例项的顺序或只显示部分图例项。使用 get_legend_handles_labels()
方法可以实现这一点。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
y3 = [3, 5, 7, 9, 11]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
ax.plot(x, y3, label='Series 3')
handles, labels = ax.get_legend_handles_labels()
ax.legend([handles[2], handles[0]], [labels[2], labels[0]], fontsize=14)
plt.title('Legend with Custom Order - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们只显示了第一个和第三个图例项,并改变了它们的顺序。
18. 使用 plt.figlegend()
创建图表级别的图例
对于包含多个子图的复杂图表,你可能想要创建一个适用于整个图表的图例。plt.figlegend()
函数可以帮助你实现这一点。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
line1, = ax1.plot(x, y1, label='Series 1')
line2, = ax1.plot(x, y2, label='Series 2')
ax2.plot(x, y2, label='Series 2')
ax2.plot(x, y1, label='Series 1')
fig.legend([line1, line2], ['Series 1', 'Series 2'], fontsize=14, loc='upper center', ncol=2)
ax1.set_title('Subplot 1 - how2matplotlib.com')
ax2.set_title('Subplot 2 - how2matplotlib.com')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们创建了两个子图,但使用 fig.legend()
创建了一个适用于整个图表的图例。
19. 使用 zorder
调整图例的层级
当你增加图例字体大小时,可能会发现图例与其他图表元素重叠。使用 zorder
参数可以调整图例的层级,确保它显示在其他元素之上。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')
ax.fill_between(x, y1, y2, alpha=0.3)
legend = ax.legend(fontsize=14, loc='center')
legend.set_zorder(100) # 确保图例显示在最上层
plt.title('Legend with Adjusted Z-order - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们使用 set_zorder(100)
将图例设置为最上层,确保它不会被其他图表元素遮挡。
20. 使用 plt.setp()
批量设置图例属性
如果你需要同时设置多个图例属性,使用 plt.setp()
函数可以使代码更简洁。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y1, label='Series 1')
ax.plot(x, y2, label='Series 2')
legend = ax.legend()
plt.setp(legend.get_texts(), fontsize=14, fontstyle='italic')
plt.setp(legend.get_title(), fontsize=16, fontweight='bold')
plt.title('Legend with Properties Set via setp() - how2matplotlib.com')
plt.show()
Output:
在这个例子中,我们使用 plt.setp()
同时设置了图例文本的字体大小和样式,以及图例标题的字体大小和粗细。
总结
通过本文,我们详细探讨了如何在 Matplotlib 中设置图例的字体大小,以及与之相关的各种技巧和最佳实践。从简单的 fontsize
参数设置,到复杂的自定义处理器和图表级别的图例,我们涵盖了多种方法来满足不同的需求。
记住,图例的字体大小不仅仅是一个孤立的设置,它通常需要与其他图表元素协调一致。在调整字体大小时,考虑图例的位置、布局、标记大小等因素,以确保整个图表的视觉平衡和可读性。
通过灵活运用这些技巧,你可以创建出既美观又信息丰富的数据可视化图表,让你的数据故事更加引人入胜。无论是用于学术论文、商业报告还是数据科学项目,掌握这些 Matplotlib 图例字体大小设置技巧都将大大提升你的数据可视化能力。