主副Y轴刻度不匹配:如何创建与主Y轴关联的副Y轴?
解决双Y轴刻度对齐问题(Gamma_ray为X轴,DEPTH与TVD_SCS_interp为Y轴)
问题背景
你需要绘制以Gamma_ray为X轴,左侧Y轴对应DEPTH、右侧Y轴对应TVD_SCS_interp的双Y轴图表,两条曲线因Gamma_ray值一致本应完全重叠,但默认双Y轴的刻度位置不匹配导致对齐偏差。
示例数据
DEPTH,TVD_SCS_interp,Gamma_ray 1000,998.5,65 1050,1047.2,72 1100,1096.0,58 1150,1144.8,68 1200,1193.5,75
原问题代码(存在刻度对齐问题)
import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data.csv') fig, ax1 = plt.subplots() # 左Y轴:DEPTH 对应 Gamma_ray ax1.plot(df['Gamma_ray'], df['DEPTH'], color='blue', label='DEPTH') ax1.set_xlabel('Gamma_ray') ax1.set_ylabel('DEPTH') ax1.invert_yaxis() # 测井数据Y轴通常向下增大,需反转 # 右Y轴:TVD_SCS_interp 对应 Gamma_ray ax2 = ax1.twinx() ax2.plot(df['Gamma_ray'], df['TVD_SCS_interp'], color='red', label='TVD_SCS_interp') ax2.set_ylabel('TVD_SCS_interp') plt.legend() plt.show()
解决方案:强制副Y轴刻度与主Y轴关联
核心思路是让副Y轴的刻度位置与主Y轴完全一致,仅替换刻度标签为TVD_SCS_interp的对应值,确保两条曲线严格对齐。
修正后代码
import pandas as pd import matplotlib.pyplot as plt import numpy as np df = pd.read_csv('data.csv') fig, ax1 = plt.subplots(figsize=(8, 10)) # 绘制主Y轴曲线(DEPTH) ax1.plot(df['Gamma_ray'], df['DEPTH'], color='blue', label='DEPTH') ax1.set_xlabel('Gamma_ray', fontsize=12) ax1.set_ylabel('DEPTH', fontsize=12) ax1.invert_yaxis() ax1.grid(True, alpha=0.3) # 创建关联副Y轴 ax2 = ax1.twinx() # 绘制副Y轴曲线(TVD_SCS_interp) ax2.plot(df['Gamma_ray'], df['TVD_SCS_interp'], color='red', linestyle='--', label='TVD_SCS_interp') ax2.set_ylabel('TVD_SCS_interp', fontsize=12) # 关键步骤:对齐刻度位置并映射对应值 # 获取主Y轴的刻度位置(对应DEPTH值) ax1_ticks = ax1.get_yticks() # 用线性插值,将主轴DEPTH刻度映射为对应的TVD_SCS_interp值 ax2_ticks = np.interp(ax1_ticks, df['DEPTH'], df['TVD_SCS_interp']) # 设置副Y轴刻度位置与主轴一致,替换标签为TVD值 ax2.set_yticks(ax1_ticks) ax2.set_yticklabels([f'{tick:.1f}' for tick in ax2_ticks]) # 强制副Y轴范围与主轴匹配,避免刻度溢出 ax2.set_ylim(ax1.get_ylim()) # 合并图例 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper right') plt.title('Gamma_ray vs DEPTH/TVD_SCS_interp', fontsize=14) plt.tight_layout() plt.show()
优化说明
- 如果
DEPTH与TVD_SCS_interp是严格线性关系(如TVD = a*DEPTH + b),可直接用线性公式计算副轴刻度,效率更高:a, b = np.polyfit(df['DEPTH'], df['TVD_SCS_interp'], 1) ax2_ticks = a * ax1_ticks + b ax1.invert_yaxis()是测井数据可视化的常规操作,确保深度数值向下递增。
内容的提问来源于stack exchange,提问作者Mahammad Ojagzada
相关产品推荐
相关产品推荐

