Matplotlib子图轴格式异常:无法自定义刻度与分箱
解决Matplotlib子图刻度与分箱不符合预期的问题
问题根源
locator_params(axis='x/y', nbins=4)是Matplotlib的建议性参数,并非强制生效。对数坐标轴(semilogy)的自动定位器会根据轴的数值范围自动调整刻度数量,导致无法得到预期的刻度分布;同时当Y轴范围的数量级跨度变化时,副刻度可能被自动隐藏。
解决方案
直接手动指定主刻度,并显式配置对数轴的副刻度:
1. X轴配置
直接设置固定刻度值[0,4,8,12,16],确保正好是4个分箱:
ax.set_xticks([0, 4, 8, 12, 16])
2. Y轴(对数轴)配置
- 手动设置主刻度(每10倍一个刻度,对应4个分箱)
- 使用
LogLocator显式启用副刻度,显示每个数量级内的中间刻度
修改后的完整代码示例
import matplotlib.pyplot as plt from matplotlib.ticker import LogLocator # 假设已定义fig_size2_x、fig_size2_y、col_gray1、col1、col2等变量 # 假设已定义r_3~r_6、r_amr、ham_3~ham_6、ham_amr、mom_z_3~mom_z_6、mom_z_amr等数据 # Figure fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize=(fig_size2_x, fig_size2_y)) # ax1配置 ax1.set_xlim([0, 16]) ax1.set_ylim([1e-4, 1e0]) ax1.set_xlabel('$r$') ax1.set_ylabel(r'$||\mathrm{Ham}||$') # X轴固定刻度 ax1.set_xticks([0, 4, 8, 12, 16]) # Y轴对数刻度配置 ax1.set_yticks([1e-4, 1e-3, 1e-2, 1e-1, 1e0]) # 启用Y轴副刻度(每个数量级显示9个中间刻度) ax1.yaxis.set_minor_locator(LogLocator(subs='all')) ax1.grid(zorder=0, color=col_gray1) # 绘制ax1曲线 ax1_line3, = ax1.semilogy(r_3, ham_3, c=col1, zorder=3, linestyle='solid', label=r'l = 3') ax1_line4, = ax1.semilogy(r_4, ham_4, c=col1, zorder=3, linestyle='solid', label=r'l = 4') ax1_line5, = ax1.semilogy(r_5, ham_5, c=col1, zorder=3, linestyle='solid', label=r'l = 5') ax1_line6, = ax1.semilogy(r_6, ham_6, c=col1, zorder=3, linestyle='solid', label=r'l = 6') ax1_lineamr, = ax1.semilogy(r_amr, ham_amr, c=col2, zorder=3, linestyle='solid', label=r'l = \mathrm{amr}') # ax2配置 ax2.set_xlim([0, 16]) ax2.set_ylim([1e-5, 1e-1]) ax2.set_xlabel('$r$') ax2.set_ylabel(r'$||\mathrm{Mom_z}||$') # X轴固定刻度 ax2.set_xticks([0, 4, 8, 12, 16]) # Y轴对数刻度配置(对应4个分箱:1e-5~1e-4, 1e-4~1e-3, 1e-3~1e-2, 1e-2~1e-1) ax2.set_yticks([1e-5, 1e-4, 1e-3, 1e-2, 1e-1]) # 启用Y轴副刻度 ax2.yaxis.set_minor_locator(LogLocator(subs='all')) ax2.grid(zorder=0, color=col_gray1) # 绘制ax2曲线 ax2_line3, = ax2.semilogy(r_3, mom_z_3, c=col1, zorder=3, linestyle='solid', label=r'l = 3') ax2_line4, = ax2.semilogy(r_4, mom_z_4, c=col1, zorder=3, linestyle='solid', label=r'l = 4') ax2_line5, = ax2.semilogy(r_5, mom_z_5, c=col1, zorder=3, linestyle='solid', label=r'l = 5') ax2_line6, = ax2.semilogy(r_6, mom_z_6, c=col1, zorder=3, linestyle='solid', label=r'l = 6') ax2_lineamr, = ax2.semilogy(r_amr, mom_z_amr, c=col2, zorder=3, linestyle='solid', label=r'l = \mathrm{amr}') # 其他子图ax3、ax4可参考上述配置 plt.tight_layout() plt.show()
关键说明
- 手动设置
xticks/yticks可以完全控制主刻度的位置,确保分箱数量符合预期 LogLocator(subs='all')会在每个数量级之间显示所有中间副刻度(比如1e-5到1e-4之间显示2e-5、3e-5...9e-5)- 如果不需要所有副刻度,可以调整
subs参数,比如subs=[2,3,4,5,6,7,8,9]只显示非10的倍数的副刻度
内容的提问来源于stack exchange,提问作者Base
相关产品推荐
相关产品推荐

