跳到主要内容Matplotlib 图表文字、刻度与图例设置详解 | 极客日志PythonAI算法
Matplotlib 图表文字、刻度与图例设置详解
本文档详细讲解了 Matplotlib 库中关于文本、刻度和图例的核心用法。涵盖了 Figure 与 Axes 层面的标题、坐标轴标签及注解设置,包括字体样式调整与全局配置。同时深入探讨了 Tick 刻度的位置控制与格式化方法,以及 Locators 和 Formatters 的高级应用。最后介绍了图例(Legend)的创建、位置布局及外观定制,提供了完整的代码示例供参考。
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
import datetime
一、Figure 和 Axes 上的文本
Matplotlib 提供了丰富的文本支持,包括数学表达式、栅格和矢量输出的 TrueType 字体、任意旋转的换行文本以及 Unicode 支持。
1. 文本 API 概览
我们可以通过 pyplot 接口和面向对象(OO)接口两种方式添加文本。下表列出了常用命令的对应关系:
| pyplot API | OO API | 说明 |
|---|
| text | text | 在子图 axes 的任意位置添加文本 |
| annotate | annotate | 在子图 axes 的任意位置添加注解,包含指向性箭头 |
| xlabel | set_xlabel | 为子图 axes 添加 x 轴标签 |
| ylabel | set_ylabel | 为子图 axes 添加 y 轴标签 |
| title | set_title | 为子图 axes 添加标题 |
| figtext | text | 在画布 figure 的任意位置添加文本 |
| suptitle | suptitle | 为画布 figure 添加标题 |
下面通过一个综合示例展示这些 API 如何协同工作。这里采用 OO 模式,后续章节会深入分析具体技巧。
fig = plt.figure()
ax = fig.add_subplot()
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': })
fig.text(, , )
ax.plot([], [], )
ax.annotate(, xy=(, ), xytext=(, ), arrowprops=(facecolor=, shrink=));
10
0.4
0.8
'This is text for figure'
2
1
'o'
'annotate'
2
1
3
4
dict
'black'
0.05
2. text - 子图上的文本
Axes.text(x, y, s, fontdict=None, **kwargs) 是核心方法。
x, y: 文本出现的位置,默认为当前坐标系下的坐标值。
s: 文本内容。
fontdict: 可选参数,用于覆盖默认文本属性。
**kwargs: 关键字参数,也可用于传入文本样式参数。
重点说明 fontdict 和 **kwargs,这两种方式调整样式的最终效果一致,不仅适用于 text,set_xlabel、set_title 等同样适用。
fig = plt.figure(figsize=(10, 3))
axes = fig.subplots(1, 2)
axes[0].text(0.3, 0.8, 'modify by **kwargs', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10});
font = {'bbox': {'facecolor': 'red', 'alpha': 0.5, 'pad': 10}, 'style': 'italic'}
axes[1].text(0.3, 0.8, 'modify by fontdict', fontdict=font);
Matplotlib 支持的样式参数非常多,建议查阅官方文档。以下是常用参数参考:
| Property | Description |
|---|
| alpha | float or None 透明度,越接近 0 越透明 |
| backgroundcolor | color 文本的背景颜色 |
| bbox | dict FancyBboxPatch 用来设置 text 周围的 box 外框 |
| color or c | color 字体的颜色 |
| fontfamily or family | {FONTNAME, 'serif', 'sans-serif'...} 字体的类型 |
| fontsize or size | float or {'xx-small'...} 字体大小 |
| fontstyle or style | {'normal', 'italic', 'oblique'} 字体的样式是否倾斜 |
| fontweight or weight | {numeric value...} 文本粗细 |
| horizontalalignment or ha | {'center', 'right', 'left'} 水平对齐方式 |
| rotation | float or {'vertical', 'horizontal'} 逆时针旋转角度 |
| verticalalignment or va | {'center', 'top', 'bottom'...} 垂直对齐方式 |
3. xlabel 和 ylabel - 子图的 x,y 轴标签
调用方式为 Axes.set_xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)。
xlabel: 标签内容。
fontdict / **kwargs: 修改样式。
labelpad: 标签和坐标轴的距离,默认为 4。
loc: 标签位置,可选 'left', 'center', 'right',默认为居中。
fig = plt.figure(figsize=(10, 3))
axes = fig.subplots(1, 2)
axes[0].set_xlabel('xlabel', labelpad=20, loc='left')
axes[1].set_xlabel('xlabel', position=(0.2, 0), horizontalalignment='left');
4. title 和 suptitle - 子图和画布的标题
Axes.set_title(label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)。
pad: 标题偏离图表顶部的距离,默认为 6。
y: title 所在子图垂向的位置,默认值为 1,即位于顶部。
suptitle 调用方式为 figure.suptitle(t, **kwargs)。
fig = plt.figure(figsize=(10, 3))
fig.suptitle('This is figure title', y=1.2)
axes = fig.subplots(1, 2)
axes[0].set_title('This is title', pad=15)
axes[1].set_title('This is title', pad=6);
5. annotate - 子图的注解
Axes.annotate(text, xy, *args, **kwargs)。
text: 注解内容。
xy: 注解箭头指向的坐标。
xytext: 注解文字的坐标。
arrowprops: 定义指向箭头的样式。
fig = plt.figure()
ax = fig.add_subplot()
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.2")
);
6. 字体的属性设置
plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(x, label='小示例图标签')
plt.xlabel('x 轴名称参数', fontproperties='Microsoft YaHei', fontsize=16)
plt.ylabel('y 轴名称参数', fontproperties='Microsoft YaHei', fontsize=14)
plt.title('坐标系的标题', fontproperties='Microsoft YaHei', fontsize=20)
plt.legend(loc='lower right', prop={"family": 'Microsoft YaHei'}, fontsize=10);
二、Tick 上的文本
设置 tick(刻度)和 ticklabel(刻度标签)是可视化中的常见需求。Matplotlib 既提供自动生成模式,也支持灵活的手动设置。
1. 简单模式
使用 axis.set_ticks 手动设置标签位置,axis.set_ticklabels 手动设置格式。
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 10.1, 2.));
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla);
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 1, figsize=(6, 4), tight_layout=True)
x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
axs[0].plot(x1, y1)
axs[0].set_xticks([0, 1, 2, 3, 4, 5, 6])
axs[1].plot(x1, y1)
axs[1].set_xticks([0, 1, 2, 3, 4, 5, 6])
axs[1].set_xticklabels(['zero', 'one', 'two', 'three', 'four', 'five', 'six'],
rotation=30, fontsize='small')
axs[1].xaxis.set_ticks_position('bottom')
print(axs[1].xaxis.get_ticklines());
2. Tick Locators and Formatters
除了简单模式,还可以使用 Locator 和 Formatter 完成设置。Axis.set_major_locator 和 Axis.set_minor_locator 设置位置,Axis.set_major_formatter 和 Axis.set_minor_formatter 设置格式。这种方式的好处是不用显式列举刻度值列表。
a) Tick Formatters
formatter 可以接收字符串格式(matplotlib.ticker.StrMethodFormatter)或函数参数(matplotlib.ticker.FuncFormatter)。
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('-%1.1f')
axs[1, 0].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
axs[1, 1].xaxis.set_major_formatter(formatter);
def formatoddticks(x, pos):
"""Format odd tick positions."""
if x % 2:
return f'{x:1.2f}'
else:
return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
ax.xaxis.set_major_formatter(formatoddticks);
b) Tick Locators
当需要更改刻度的位置时,Matplotlib 提供了常用的几种 locator 类型。
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
locator = matplotlib.ticker.AutoLocator()
axs[0, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MaxNLocator(nbins=3)
axs[0, 1].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MultipleLocator(5)
axs[1, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.FixedLocator([0, 7, 14, 21, 28])
axs[1, 1].xaxis.set_major_locator(locator);
此外 matplotlib.dates 模块还提供了特殊的日期型刻度格式和位置设置。
locator = mdates.DayLocator(bymonthday=[1, 15, 25])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70);
三、legend(图例)
- legend entry: 图例条目,包含 key 和 label。
- legend key: legend label 左侧的彩色/图案标记。
- legend label: 描述 handle 的文本。
- legend handle: 生成图例条目的原始对象。
图例绘制有 OO 模式和 pyplot 模式,写法相同,使用 legend() 即可。通常不传参,Matplotlib 会自动寻找合适的条目;也可以手动传入句柄和标签。
fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend(handles=[line_up, line_down], labels=['Line Up', 'Line Down']);
设置图例位置
loc 参数接收字符串或数字表示位置。例如 ax.legend(loc='upper center') 等同于 ax.legend(loc=9)。
| Location String | Location Code |
|---|
| 'best' | 0 |
| 'upper right' | 1 |
| 'upper left' | 2 |
| 'lower left' | 3 |
| 'lower right' | 4 |
| 'right' | 5 |
| 'center left' | 6 |
| 'center right' | 7 |
| 'lower center' | 8 |
| 'upper center' | 9 |
| 'center' | 10 |
fig, axes = plt.subplots(1, 4, figsize=(10, 4))
for i in range(4):
axes[i].plot([0.5], [0.5])
axes[i].legend(labels='a', loc=i)
fig.tight_layout()
设置图例边框及背景
fig = plt.figure(figsize=(10, 3))
axes = fig.subplots(1, 3)
for i, ax in enumerate(axes):
ax.plot([1, 2, 3], label=f'ax {i}')
axes[0].legend(frameon=False)
axes[1].legend(edgecolor='blue')
axes[2].legend(facecolor='gray');
设置图例标题
fig, ax = plt.subplots()
ax.plot([1, 2, 3], label='label')
ax.legend(title='legend title');
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online