开启usetex=True时Matplotlib次X轴字体与主轴不一致的解决方法
问题:Matplotlib次X轴字体与主X轴不一致
运行以下最小复现代码后,次X轴标注的5和10字体与主X轴(30、40、50)不一致,尝试单独设置轴标签、为文本添加$$等LaTeX格式均未解决,需要实现字体统一。
import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt # Use latex import os os.environ["PATH"] += os.pathsep + '/usr/local/texlive/2024/bin/x86_64-linux' if __name__ == '__main__': test_data = 10 test_data_2 = 24 # Create plot and axis fig, ax = plt.subplots() plt.rcParams.update({ "text.usetex": True, "font.family": "serif", "font.serif": "Computer Modern Roman", }) # Plot ax.plot([i for i in range(test_data)], [i for i in range(test_data)], label="Test") ax.tick_params(bottom=False) # Define x axis x_axis = ['30', '40', '50'] * (test_data_2 // 3) ax.set_xticks(range(len(x_axis)), labels=(x_axis)) # Add second x axis sec2 = ax.secondary_xaxis(location=0) sec2.set_xticks([5.5 + 12 * i for i in range(test_data_2 // 12)], labels=[f'\n\n\n{5 + i * 5}' for i in range(test_data_2 // 12)]) sec2.tick_params('x', length=0) plt.show()
解决方案
问题根源在于全局字体设置时机错误,且次X轴标签未正确触发LaTeX渲染,按以下步骤修改即可:
1. 提前更新全局字体参数
将plt.rcParams.update()移到创建绘图对象(plt.subplots())之前,确保所有后续创建的轴都继承统一的字体配置。
2. 用LaTeX语法处理次X轴标签
带换行符的纯文本标签可能无法自动触发LaTeX解析,改用LaTeX的换行语法\\替代Python的\n,并确保标签内容被LaTeX环境解析。
修改后的完整代码:
import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt # Use latex import os os.environ["PATH"] += os.pathsep + '/usr/local/texlive/2024/bin/x86_64-linux' if __name__ == '__main__': test_data = 10 test_data_2 = 24 # 先更新全局参数,再创建绘图对象 plt.rcParams.update({ "text.usetex": True, "font.family": "serif", "font.serif": "Computer Modern Roman", }) # Create plot and axis fig, ax = plt.subplots() # Plot ax.plot([i for i in range(test_data)], [i for i in range(test_data)], label="Test") ax.tick_params(bottom=False) # Define x axis x_axis = ['30', '40', '50'] * (test_data_2 // 3) ax.set_xticks(range(len(x_axis)), labels=(x_axis)) # Add second x axis sec2 = ax.secondary_xaxis(location=0) # 用LaTeX换行语法替代纯文本换行,确保字体统一 sec2.set_xticks( [5.5 + 12 * i for i in range(test_data_2 // 12)], labels=[f'\\vspace{1em}\\{5 + i * 5}' for i in range(test_data_2 // 12)] ) sec2.tick_params('x', length=0) plt.show()
额外兼容方案
如果仍存在字体差异,可以显式指定次X轴标签的字体属性:
sec2.set_xticklabels( [f'\\vspace{1em}\\{5 + i * 5}' for i in range(test_data_2 // 12)], fontfamily='serif', fontname='Computer Modern Roman' )
内容的提问来源于stack exchange,提问作者Raoul Luqué
相关产品推荐
相关产品推荐

