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

为Matplotlib对数X轴添加自定义刻度及个性化网格线

解决对数X轴自定义刻度标签与网格线问题

我来帮你搞定这个对数轴自定义刻度的问题——你遇到的核心问题是:对数轴的默认格式化器只会处理它自动生成的刻度,手动添加的主刻度不会自动生成标签。这里有两种可行的解决方案,先说说最终更灵活的那个:

推荐方案:次要刻度+自定义辅助线

这种方式不会干扰原有主刻度的布局,还能灵活控制标签和网格样式,就是你最终采用的思路,我来拆解下关键步骤:

  1. 定义自定义刻度标签格式化函数
    这个函数用来指定40000位置的显示文本,用LaTeX语法可以让乘号更美观:

    def log_format(x, pos):
        return "$200\times 200$"
    
  2. 将自定义刻度设为次要刻度
    避免和主刻度的自动生成逻辑冲突:

    ax.set_xticks([200*200], minor=True)
    
  3. 关闭次要刻度默认网格,绘制自定义网格线
    用axvline可以完全自定义网格的颜色、线型:

    ax.xaxis.grid(False, which="minor")  # 关闭默认次要网格
    ax.axvline(200*200, color='white', linestyle="--")  # 自定义网格线
    
  4. 添加注释文本(可选)
    给这个关键刻度加个说明,让图表更易懂:

    ymin,ymax = ax.get_ylim()
    ax.text(200*200 - 200*50, (ymax-ymin)/2, "Default render size", rotation=90, va="center", style="italic")
    
  5. 给次要刻度绑定自定义格式化器
    让40000位置显示你想要的标签:

    ax.xaxis.set_minor_formatter(FuncFormatter(log_format))
    

完整的最终代码如下:

from matplotlib.pyplot import figure, FuncFormatter, show
import numpy as np

def log_format(x, pos):
    return "$200\times 200$"
fig = figure(figsize=(12, 8))
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.power(sizes, 2), hsv_mat_times, label="HSV Material Shader")
ax.plot(np.power(sizes, 2), brick_mat_times, label="Brick Material Shader")
ax.plot(np.power(sizes, 2), hsv_mat_times2, label="PLACEHOLDER FOR 3rd shader")
ax.set_title("Python Shader Rendering Performance", fontsize=18)
ax.set_xlabel("Number of Pixels")
ax.set_ylabel("CPU Rendering Time (ms)")
ax.set_xscale("log")
ax.set_xticks([200*200], minor=True)
ax.xaxis.grid(False, which="minor")
ax.axvline(200*200, color='white', linestyle="--")
ymin,ymax = ax.get_ylim()
ax.text(200*200 - 200*50, (ymax-ymin)/2, "Default render size", rotation=90, va="center", style="italic")
ax.xaxis.set_minor_formatter(FuncFormatter(log_format))
ax.legend()
show()

备选方案:手动设置主刻度标签

如果你坚持要把40000作为主刻度,那需要手动生成所有主刻度的标签,避免默认格式化器忽略自定义刻度:

xticks = np.logspace(2,6,num=5)
xticks = np.insert(xticks,4,200*200)
# 手动生成每个刻度的标签
xtick_labels = []
for tick in xticks:
    if tick == 200*200:
        xtick_labels.append("$200\times 200$")
    else:
        xtick_labels.append("{:.3}".format(tick / 1000000))  # 复用你原来的格式化逻辑
ax.set_xticks(xticks)
ax.set_xticklabels(xtick_labels)

不过这个方案的缺点是,当主刻度范围变化时,你需要手动调整标签列表,灵活性不如次要刻度方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:17:36