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

Matplotlib 3.2.1对数Y轴部分次要刻度标签缺失问题求助

解决Matplotlib 3.2.1中对数Y轴3倍次要刻度标签缺失的问题

问题背景

在Matplotlib 3.2.1版本中自定义对数Y轴的主次刻度标签,要求所有标签采用%g格式。当次要刻度设置为2、5的倍数时显示正常,但改为3的倍数后,0.3的标签缺失。相关修改后的代码片段如下:

minor_ticks = [0.003, 0.03, 0.3, 3, 30]
minor_locator = ticker.LogLocator(base=10.0, subs=[0.3], numticks=12)

由于环境限制无法升级Matplotlib版本,需要找到兼容的解决方法。

原因分析

Matplotlib 3.2.1的LogLocator在生成subs=[0.3]对应的刻度时,会因浮点数精度问题生成近似值(例如0.30000000000000004),而原代码中使用val in minor_ticks的精确匹配会判定该值不在目标列表中,导致0.3的标签无法显示。

解决方案

以下两种方法均可解决该问题,无需升级Matplotlib版本:

方法一:使用模糊匹配替代精确判断

修改次要刻度的格式化函数,通过np.isclose()判断刻度值是否近似等于目标值,避免浮点数精度问题:

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

N = 100
x = np.linspace(0, 1, N)
np.random.seed(123)
y = np.random.uniform(0.1, 50, N)

fig, ax = plt.subplots()
ax.plot(x, y)

ax.set(yscale="log")
# 主刻度设置
major_ticks = [0.001, 0.01, 0.1, 1, 10, 100]
ax.set_yticks(major_ticks)
ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%g"))

# 次要刻度设置
minor_ticks = [0.003, 0.03, 0.3, 3, 30]
minor_locator = ticker.LogLocator(base=10.0, subs=[0.3], numticks=12)

def minor_tick_filter(val, pos):
    # 用极小误差范围匹配近似值
    for tick_val in minor_ticks:
        if np.isclose(val, tick_val, rtol=1e-8):
            return '%g' % tick_val
    return ''

ax.yaxis.set_minor_locator(minor_locator)
ax.yaxis.set_minor_formatter(ticker.FuncFormatter(minor_tick_filter))

ax.set(xlim=[0, 1], ylim=[0.1, 100])
plt.minorticks_on()
plt.show()

方法二:手动指定次要刻度位置

跳过LogLocator,直接通过ax.set_yticks()手动设置次要刻度的位置,避免自动生成的精度问题:

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

N = 100
x = np.linspace(0, 1, N)
np.random.seed(123)
y = np.random.uniform(0.1, 50, N)

fig, ax = plt.subplots()
ax.plot(x, y)

ax.set(yscale="log")
# 主刻度设置
major_ticks = [0.001, 0.01, 0.1, 1, 10, 100]
ax.set_yticks(major_ticks)
ax.yaxis.set_major_formatter(ticker.FormatStrFormatter("%g"))

# 次要刻度设置:直接指定位置
minor_ticks = [0.003, 0.03, 0.3, 3, 30]
ax.set_yticks(minor_ticks, minor=True)
ax.yaxis.set_minor_formatter(ticker.FormatStrFormatter("%g"))

ax.set(xlim=[0, 1], ylim=[0.1, 100])
plt.minorticks_on()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:13:17