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

如何修改plotnine/matplotlib中指数标签的字体?

解决plotnine对数轴指数标签字体不生效问题

问题现象

使用plotnine绘制带对数刻度Y轴的图表时,通过theme(text=element_text(family="Gill Sans"))全局设置字体后,图表中除Y轴指数标签外的所有文本均正常应用Gill Sans字体,但指数标签仍保留默认字体。

原因分析

问题出在label_log(mathtex=True)参数上:开启mathtex=True后,Y轴的指数标签会以LaTeX数学公式的形式渲染,这类文本会使用matplotlib默认的数学字体,不受plotnine的全局主题字体设置影响。

解决方案

提供两种可行的解决方式:

方式一:自定义标签生成函数(不依赖mathtex)

手动生成指数格式的文本标签,让标签继承全局字体设置:

import plotnine as p9
import pandas as pd
import mizani
import numpy as np

def custom_log_labels(x):
    # 手动转换为10的指数格式文本
    return [f"$10^{{{int(np.log10(val))}}}$" if val != 0 else "0" for val in x]

data = {
    "Degree": [3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6],
    "Probability": [0.00001, 0.00002, 0.00003, 0.001, 0.002, 0.003, 0.01, 0.02, 0.03, 0.1, 0.2, 0.3],
    "p": ["p=0.01", "p=0.01", "p=0.01", "p=0.1", "p=0.1", "p=0.1", "p=0.01", "p=0.01", "p=0.01", "p=0.1", "p=0.1", "p=0.1"],
    "Scheme": ["Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed"],
}

df = pd.DataFrame(data)

x_val = "Degree"
y_val = "Probability"
y_label = "Degree Probability"
g1_val = "p"
g2_val = "Scheme"

p = (
    p9.ggplot(df)
    + p9.aes(x=x_val, y=y_val, color=g1_val, shape=g2_val, linetype=g2_val, size=g2_val)
    + p9.geom_point(alpha=0.8)
    + p9.geom_line(size=0.5)
    + p9.scale_x_continuous(name=x_val, breaks=[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
    # 使用自定义标签函数,替代mathtex渲染
    + p9.scale_y_continuous(name=y_label, trans=mizani.transforms.log_trans(10), labels=custom_log_labels)
    + p9.geom_vline(xintercept=6, size=0.4, linetype="dotted", color="black")
    + p9.geom_vline(xintercept=3, size=0.4, linetype="dotted", color="black")
    + p9.scale_shape_manual(name="Algorithm", values=["o", "*", "+"])
    + p9.scale_color_manual(name="Rewiring Prob.", values=["red", "blue"])
    + p9.scale_linetype_manual(name="Algorithm", values=["none", "none", "solid"])
    + p9.scale_size_manual(name="Algorithm", values=[5, 5, 2])
    + p9.theme(text=p9.element_text(family="Gill Sans", weight="regular"))
)

p

方式二:修改matplotlib全局配置,强制数学文本使用目标字体

通过设置matplotlib的rc参数,让LaTeX渲染的数学文本也使用Gill Sans字体:

import plotnine as p9
import pandas as pd
import mizani
import matplotlib.pyplot as plt

# 设置matplotlib的数学文本字体
plt.rcParams['mathtext.fontset'] = 'custom'
plt.rcParams['mathtext.rm'] = 'Gill Sans'
plt.rcParams['mathtext.it'] = 'Gill Sans:italic'
plt.rcParams['mathtext.bf'] = 'Gill Sans:bold'

data = {
    "Degree": [3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6],
    "Probability": [0.00001, 0.00002, 0.00003, 0.001, 0.002, 0.003, 0.01, 0.02, 0.03, 0.1, 0.2, 0.3],
    "p": ["p=0.01", "p=0.01", "p=0.01", "p=0.1", "p=0.1", "p=0.1", "p=0.01", "p=0.01", "p=0.01", "p=0.1", "p=0.1", "p=0.1"],
    "Scheme": ["Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed", "Theoretical", "Original", "Proposed"],
}

df = pd.DataFrame(data)

x_val = "Degree"
y_val = "Probability"
y_label = "Degree Probability"
g1_val = "p"
g2_val = "Scheme"

p = (
    p9.ggplot(df)
    + p9.aes(x=x_val, y=y_val, color=g1_val, shape=g2_val, linetype=g2_val, size=g2_val)
    + p9.geom_point(alpha=0.8)
    + p9.geom_line(size=0.5)
    + p9.scale_x_continuous(name=x_val, breaks=[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
    + p9.scale_y_continuous(name=y_label, trans=mizani.transforms.log_trans(10), labels=mizani.labels.label_log(mathtex=True))
    + p9.geom_vline(xintercept=6, size=0.4, linetype="dotted", color="black")
    + p9.geom_vline(xintercept=3, size=0.4, linetype="dotted", color="black")
    + p9.scale_shape_manual(name="Algorithm", values=["o", "*", "+"])
    + p9.scale_color_manual(name="Rewiring Prob.", values=["red", "blue"])
    + p9.scale_linetype_manual(name="Algorithm", values=["none", "none", "solid"])
    + p9.scale_size_manual(name="Algorithm", values=[5, 5, 2])
    + p9.theme(text=p9.element_text(family="Gill Sans", weight="regular"))
)

p

说明

  • 方式一无需依赖LaTeX渲染,直接生成普通文本标签,兼容性更好,但需要自己处理标签格式;
  • 方式二保留了mathtex的渲染效果,同时强制数学文本使用目标字体,适合需要保持公式排版风格的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:34:56