Matplotlib启用LaTeX致图例与Y轴刻度标签错位问题求助
Matplotlib启用LaTeX后布局错位(图例、对数刻度)及siunitx使用解决方案
问题描述
在Matplotlib中启用text.usetex = True以使用LaTeX的siunitx包格式化SI单位时,会出现图例标签错位、对数刻度Y轴标签与刻度不对齐的布局问题;但关闭该选项后,布局恢复正常却无法使用siunitx语法。
复现代码
import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams['text.usetex'] = True mpl.rcParams['text.latex.preamble'] = r'\usepackage{siunitx}' mpl.rcParams['legend.fontsize'] = 14 mpl.rcParams['xtick.labelsize'] = 15 mpl.rcParams['ytick.labelsize'] = 15 mpl.rcParams['axes.labelsize'] = 18 mpl.rcParams['figure.titlesize'] = 18 DOTSIZE = 3.5 X = np.linspace(0.001,1,1000) fig = plt.figure(figsize = (10,6)) plt.plot(X, X, label = 'data') plt.title(r'using SI Units like $\SI{100}{\hertz}$', fontsize = 20) plt.yscale('log') plt.xscale('log') plt.grid(color = 'grey', which = 'both', alpha = 0.4, linestyle = '--', linewidth = 1) plt.legend() plt.savefig('test.pdf') plt.show()
问题成因
- 启用原生LaTeX渲染时,Matplotlib会将所有文本(包括刻度、图例)交给LaTeX处理,而LaTeX的文本排版逻辑与Matplotlib内置渲染引擎存在差异,尤其是对数刻度的上标标签(如
10^-3)和图例的文本对齐计算会出现偏差。 - 部分Matplotlib版本中,
text.latex.preamble的配置方式可能存在兼容性问题,导致siunitx包加载不完全或渲染逻辑冲突。
解决方案
方案1:调整LaTeX渲染的布局参数
通过配置额外的Matplotlib参数,修正文本对齐与图例错位问题:
import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl # 启用LaTeX并配置siunitx,添加布局修正参数 mpl.rcParams['text.usetex'] = True mpl.rcParams['text.latex.preamble'] = r'\usepackage{siunitx}' # 强制使用LaTeX字体度量,避免Matplotlib字体覆盖 mpl.rcParams['pgf.rcfonts'] = False mpl.rcParams['pgf.preamble'] = r'\usepackage{siunitx}' # 显式设置刻度标签对齐方式 mpl.rcParams['xtick.alignment'] = 'center' mpl.rcParams['ytick.alignment'] = 'center' # 原有字体配置 mpl.rcParams['legend.fontsize'] = 14 mpl.rcParams['xtick.labelsize'] = 15 mpl.rcParams['ytick.labelsize'] = 15 mpl.rcParams['axes.labelsize'] = 18 mpl.rcParams['figure.titlesize'] = 18 DOTSIZE = 3.5 X = np.linspace(0.001,1,1000) fig = plt.figure(figsize = (10,6)) plt.plot(X, X, label = 'data') plt.title(r'using SI Units like $\SI{100}{\hertz}$', fontsize = 20) plt.yscale('log') plt.xscale('log') plt.grid(color = 'grey', which = 'both', alpha = 0.4, linestyle = '--', linewidth = 1) # 手动调整图例位置,避免错位 plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.) # 保存时使用tight参数防止内容截断 plt.savefig('test.pdf', bbox_inches='tight') plt.show()
关键调整点:
- 添加
pgf.rcfonts = False和pgf.preamble配置,确保LaTeX字体与渲染逻辑一致性 - 显式设置刻度对齐为
center,修正对数刻度标签错位 - 手动指定图例的
bbox_to_anchor参数,解决图例偏移问题 - 保存文件时使用
bbox_inches='tight',避免LaTeX渲染的文本被截断
方案2:仅对需要siunitx的文本使用LaTeX渲染
不全局启用text.usetex,仅在需要使用siunitx的标题/标签中嵌入LaTeX片段,同时用Matplotlib原生工具处理对数刻度:
import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl from matplotlib.ticker import LogFormatterSciNotation # 不全局启用LaTeX,仅允许解析LaTeX数学片段 mpl.rcParams['text.usetex'] = False mpl.rcParams['mathtext.fontset'] = 'cm' # 预加载siunitx包 mpl.rcParams['text.latex.preamble'] = r'\usepackage{siunitx}' # 原有字体配置 mpl.rcParams['legend.fontsize'] = 14 mpl.rcParams['xtick.labelsize'] = 15 mpl.rcParams['ytick.labelsize'] = 15 mpl.rcParams['axes.labelsize'] = 18 mpl.rcParams['figure.titlesize'] = 18 DOTSIZE = 3.5 X = np.linspace(0.001,1,1000) fig = plt.figure(figsize = (10,6)) plt.plot(X, X, label = 'data') # 标题中嵌入siunitx的LaTeX代码 plt.title(r'using SI Units like $\SI{100}{\hertz}$', fontsize = 20) plt.yscale('log') plt.xscale('log') # 使用Matplotlib原生对数刻度格式化器,避免LaTeX渲染偏差 plt.gca().yaxis.set_major_formatter(LogFormatterSciNotation(labelOnlyBase=False)) plt.gca().xaxis.set_major_formatter(LogFormatterSciNotation(labelOnlyBase=False)) plt.grid(color = 'grey', which = 'both', alpha = 0.4, linestyle = '--', linewidth = 1) plt.legend() plt.savefig('test.pdf') plt.show()
关键优势:
- 保留siunitx的使用能力,同时避免全局LaTeX渲染带来的布局问题
- 对数刻度使用Matplotlib原生渲染,标签对齐完全正常
方案3:更新依赖版本
部分旧版本Matplotlib与siunitx包存在兼容性问题,尝试更新到最新稳定版:
- 更新Matplotlib:
pip install --upgrade matplotlib - 确保系统LaTeX环境(TeX Live/MiKTeX)安装了最新版siunitx包,可通过包管理器更新
内容的提问来源于stack exchange,提问作者Solidstateman
相关产品推荐
相关产品推荐

