制作适用于 LaTeX 的专业 Matplotlib 图像
🔠 字体
字体样式
为了确保 Matplotlib 图像中的字体与 LaTeX 正文中的字体完全一致,最佳做法是使用 LaTeX 进行字体渲染。这可以 100% 保证字体风格的一致性。
安装 TeX Live
请在系统中安装 TeX Live:
- macOS:
brew install texlive - Debian / Ubuntu:
apt install texlive-full - Windows:请参考 官方指南
安装完成后,请确保 pdflatex 可执行文件已正确加入到 PATH 中。
启用 LaTeX 字体渲染
import matplotlib.pyplot as plt
plt.rcParams.update({
"text.usetex": True,
"font.family": "Computer Modern",
})
字体大小
使用与 LaTeX 正文一致的字体大小,是获得专业外观的关键。虽然这一点在概念上非常简单,但在实际操作中,许多人仍然会在图例、刻度标签、图标题等元素的字体大小调整上遇到困难。
关键在于:字体大小是相对于图像尺寸而言的。 如果图像本身设置得过大,即使使用较大的字体参数,当图像插入到文档中时,文字仍然可能显得很小。
因此,字体大小控制中最重要、也是第一步,是正确设置图像尺寸。 其基本原则非常简单:图像的宽度应当与其在文档中的最终显示宽度完全一致。
如下图所示,对于 IEEE 双栏格式中的单栏图像,其列宽大约为 3.5 英寸。 只需将图像宽度设置为 3.5 英寸,字体大小就会自然地与 LaTeX 正文保持一致,而无需额外微调。

IEEE 双栏格式中,单栏列宽约为 3.5 英寸。
- 将图像宽度设置为与文档中显示宽度一致。在 IEEE 风格的双栏排版中,单栏宽度通常为 3.5 英寸。因此,对于单栏图像,只需将图像宽度设置为 3.5 英寸:
fig = plt.figure(figsize=(3.5, 3.5))
- 将字体大小设置为默认值,在 IEEE 模板中,默认字体为10pt,因此只需要将字体大小设置为10
import matplotlib as mpl
mpl.rcParams.update({
"font.size": 10,
"axes.labelsize": 10,
"axes.titlesize": 10,
"figure.titlesize": 10,
"legend.fontsize": 9,
"xtick.labelsize": 9,
"ytick.labelsize": 9,
})
就这么简单——图像中的文字现在将与 LaTeX 正文中的字体保持一致。
📊 Matplotlib Legend 的精细控制
Legend 是 Matplotlib 坐标轴中的一个重要组成部分,用于标识和区分图中的不同元素。
Legend Location: loc
使用 legend(loc=) 指定图例的位置。
该参数既可以是精确坐标,也可以是字符串形式的位置描述,例如
For example: ax.legend(loc=(0, 0.5)) or ax.legend("upper left").
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(i/3, i/3))
plt.tight_layout()
Legend at different locations.
字体大小:fontsize
使用 legend(fontsize=) 指定图例字体大小。
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), fontsize=8+i*3)
plt.tight_layout()
Legend with various font sizes.
列数:ncol
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=i+1)
plt.tight_layout()
Legends of different columns.
行间距:labelspacing
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, labelspacing=2*i)
plt.tight_layout()
Adjust the spacing between columns.
列间距:columnspacing
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, columnspacing=2*i)
plt.tight_layout()
Adjust the spacing between columns.
Handle 长度: handlelength
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, handlelength=i+1)
plt.tight_layout()
Adjust handle length.
Handle 与文本之间的间距:handletextpad
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, handletextpad=i)
plt.tight_layout()
Space between handle and text.