You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib文献风格轴科学计数法:如何修改默认字体?

解决Matplotlib双坐标轴特定字体的文献风格科学计数法问题

问题背景

已通过自定义MathTextSciFormatter实现文献风格的科学计数法坐标轴标签,但无法通过plt.xticks(font="Arial")或tick.set_fontname("Arial")修改字体(仅字号可调),使用版本为Matplotlib 3.5.3。

问题原因

自定义Formatter返回的是LaTeX数学模式字符串(用$...$包裹),Matplotlib会使用数学字体渲染这类内容,普通的tick标签字体设置不会作用于数学模式文本。

解决方案

方法1:全局配置数学文本字体

通过修改Matplotlib的rc参数,指定数学模式下使用目标字体(如Arial),适用于全局所有数学文本:

修改代码开头,添加以下配置:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker

# 配置数学文本使用Arial字体
plt.rcParams['mathtext.fontset'] = 'custom'
plt.rcParams['mathtext.rm'] = 'Arial'
plt.rcParams['mathtext.it'] = 'Arial:italic'
plt.rcParams['mathtext.bf'] = 'Arial:bold'

# 后续原代码保持不变
fig,ax=plt.subplots(1,1,figsize=[7,7])
x=np.linspace(0,0.1,10**3)
y=x**2
ax.plot(x,y)

# 原自定义Formatter代码
class MathTextSciFormatter(mticker.Formatter):
    def __init__(self, fmt="%1.2e"):
        self.fmt = fmt
    def __call__(self, x, pos=None):
        s = self.fmt % x
        decimal_point = '.'
        positive_sign = '+'
        tup = s.split('e')
        significand = tup[0].rstrip(decimal_point)
        sign = tup[1][0].replace(positive_sign, '')
        exponent = tup[1][1:].lstrip('0')
        if exponent:
            exponent = '10^{%s%s}' % (sign, exponent)
        if significand and exponent:
            s =  r'%s{\times}%s' % (significand, exponent)
        else:
            s =  r'%s%s' % (significand, exponent)
        return "${}$".format(s)

plt.gca().xaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))
plt.gca().yaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))

plt.xticks(rotation=45, font="Arial", fontsize=20)
for tick in ax.get_yticklabels():
    tick.set_fontname("Arial")

方法2:在Formatter中强制使用文本字体

修改自定义MathTextSciFormatter的返回逻辑,将有效数字部分用\mathrm{}包裹,强制使用文本字体:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker

fig,ax=plt.subplots(1,1,figsize=[7,7])
x=np.linspace(0,0.1,10**3)
y=x**2
ax.plot(x,y)

# 修改后的自定义Formatter
class MathTextSciFormatter(mticker.Formatter):
    def __init__(self, fmt="%1.2e"):
        self.fmt = fmt
    def __call__(self, x, pos=None):
        s = self.fmt % x
        decimal_point = '.'
        positive_sign = '+'
        tup = s.split('e')
        significand = tup[0].rstrip(decimal_point)
        # 用\mathrm{}包裹有效数字,强制使用文本字体
        significand = r'\mathrm{%s}' % significand
        sign = tup[1][0].replace(positive_sign, '')
        exponent = tup[1][1:].lstrip('0')
        if exponent:
            exponent = '10^{%s%s}' % (sign, exponent)
        if significand and exponent:
            s =  r'%s{\times}%s' % (significand, exponent)
        else:
            s =  r'%s%s' % (significand, exponent)
        return "${}$".format(s)

plt.gca().xaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))
plt.gca().yaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))

# 字体设置生效
plt.xticks(rotation=45, font="Arial", fontsize=20)
for tick in ax.get_yticklabels():
    tick.set_fontname("Arial")
    tick.set_fontsize(20)

验证说明

两种方法均可让坐标轴的科学计数法标签使用Arial字体,方法1适合全局统一配置,方法2更灵活,可针对特定Formatter单独设置。

内容的提问来源于stack exchange,提问作者vrvn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:00:21