Matplotlib中Semilogy绘图对数刻度标记显示不一致问题
Matplotlib semilogy子图对数刻度显示异常问题
我使用Matplotlib的semilogy绘制ax1和ax2两个子图,代码逻辑完全一致,但仅ax2显示y轴对数刻度标记。尝试过ax1.yaxis.set_major_locator(plt.LogLocator(base=10.0, numticks=15))仍未解决,需要实现ax1自动显示对数刻度标记。
相关代码如下:
def plot_optimization_results(history): """ Plot the optimization results """ iterations = [h['iteration'] for h in history] f_values = [h['f'] for h in history] F_norms = [h['grad_norm'] for h in history] x_values = np.array([h['x'] for h in history]) # Create figure with subplots fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5)) # Plot merit function value ax1.semilogy(iterations, f_values) ax1.xaxis.set_major_locator(plt.MultipleLocator(5)) ax1.set_xlabel('Iteration') ax1.set_ylabel('Merit Function Value') ax1.set_title('Convergence of Merit Function') ax1.grid(True) # Plot norm of F(x) ax2.semilogy(iterations, F_norms) ax2.xaxis.set_major_locator(plt.MultipleLocator(5)) ax2.set_xlabel('Iteration') ax2.set_ylabel('||F(x)||') ax2.set_title('Norm of F(x) vs Iteration') ax2.grid(True) ... return fig
效果截图:
问题原因与解决办法
这种情况通常是因为ax1中f_values的数据范围过窄,Matplotlib自动隐藏了部分刻度标记。可以通过以下几种方式解决:
1. 强制显示所有刻度标记
在ax1的绘图代码后添加以下代码,强制开启主、次刻度的显示:
# 设置主刻度定位器 ax1.yaxis.set_major_locator(plt.LogLocator(base=10.0, numticks=15)) # 设置次刻度定位器,显示所有中间刻度线 ax1.yaxis.set_minor_locator(plt.LogLocator(base=10.0, subs='all')) # 强制显示y轴的主、次刻度 ax1.tick_params(axis='y', which='both', visible=True)
2. 手动指定y轴范围
如果f_values的数据范围确实很小,可以手动扩大y轴的对数范围,给刻度标记留出足够空间:
ax1.set_ylim(bottom=min(f_values)*0.1, top=max(f_values)*10)
3. 强制格式化刻度标签
使用LogFormatterSciNotation确保刻度标签正确渲染:
from matplotlib.ticker import LogFormatterSciNotation ax1.yaxis.set_major_formatter(LogFormatterSciNotation(base=10.0))
修改后的完整代码示例
import matplotlib.pyplot as plt from matplotlib.ticker import LogLocator, LogFormatterSciNotation import numpy as np def plot_optimization_results(history): """ Plot the optimization results """ iterations = [h['iteration'] for h in history] f_values = [h['f'] for h in history] F_norms = [h['grad_norm'] for h in history] x_values = np.array([h['x'] for h in history]) # Create figure with subplots fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5)) # Plot merit function value ax1.semilogy(iterations, f_values) ax1.xaxis.set_major_locator(plt.MultipleLocator(5)) # 解决对数刻度不显示问题 ax1.yaxis.set_major_locator(LogLocator(base=10.0, numticks=15)) ax1.yaxis.set_minor_locator(LogLocator(base=10.0, subs='all')) ax1.tick_params(axis='y', which='both', visible=True) ax1.set_xlabel('Iteration') ax1.set_ylabel('Merit Function Value') ax1.set_title('Convergence of Merit Function') ax1.grid(True) # Plot norm of F(x) ax2.semilogy(iterations, F_norms) ax2.xaxis.set_major_locator(plt.MultipleLocator(5)) ax2.set_xlabel('Iteration') ax2.set_ylabel('||F(x)||') ax2.set_title('Norm of F(x) vs Iteration') ax2.grid(True) ... return fig
内容的提问来源于stack exchange,提问作者Thibaultofc
相关产品推荐
相关产品推荐

