为Matplotlib对数X轴添加自定义刻度及个性化网格线
解决对数X轴自定义刻度标签与网格线问题
我来帮你搞定这个对数轴自定义刻度的问题——你遇到的核心问题是:对数轴的默认格式化器只会处理它自动生成的刻度,手动添加的主刻度不会自动生成标签。这里有两种可行的解决方案,先说说最终更灵活的那个:
推荐方案:次要刻度+自定义辅助线
这种方式不会干扰原有主刻度的布局,还能灵活控制标签和网格样式,就是你最终采用的思路,我来拆解下关键步骤:
定义自定义刻度标签格式化函数
这个函数用来指定40000位置的显示文本,用LaTeX语法可以让乘号更美观:def log_format(x, pos): return "$200\times 200$"将自定义刻度设为次要刻度
避免和主刻度的自动生成逻辑冲突:ax.set_xticks([200*200], minor=True)关闭次要刻度默认网格,绘制自定义网格线
用axvline可以完全自定义网格的颜色、线型: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")给次要刻度绑定自定义格式化器
让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
相关产品推荐
相关产品推荐

