Python/matplotlib实现与主轴函数关联、同位置的非线性次轴刻度
Python matplotlib 非线性关联次坐标轴实现方法
核心使用matplotlib自带的secondary_yaxis接口实现需求,无需修改原有图形、也不用手动硬设刻度标签,次坐标轴会自动和主坐标轴刻度位置对齐,仅按自定义函数转换刻度显示值,缩放时也会自动同步更新。
通用示例(对应你举的f(y)=5y²+2场景)
import matplotlib.pyplot as plt import numpy as np # 原始绘图逻辑:绘制y=x直线 x = np.arange(0, 5, 0.1) y = x fig, ax = plt.subplots() ax.plot(x, y) ax.set_ylabel('原始主Y轴:y值') ax.set_ylim(0, 4) # 定义正向转换:主轴数值 → 次轴显示数值 def y_to_f(y): return 5 * y ** 2 + 2 # 定义反向转换:次轴数值 → 主轴数值(供matplotlib内部定位用,必须定义) def f_to_y(f): return np.sqrt((f - 2) / 5) # 新增右侧次Y轴 sec_ax = ax.secondary_yaxis('right', functions=(y_to_f, f_to_y)) sec_ax.set_ylabel('次Y轴:f(y)=5y²+2') plt.show()
运行后主轴1、2、3、4的刻度位置,次轴对应显示7、22、47、82,完全符合需求。
适配你的业务代码
你需要先确认Max position (mm)和Oscillation frequency (kHz)之间的正反转换逻辑,替换代码中的对应函数即可:
import matplotlib.pyplot as plt # 初始化画布与主坐标轴 fig, ax1 = plt.subplots() # 绘制时间-位置曲线,使用左侧主Y轴 ax1.plot(time_max_axis, position_max_axis) ax1.set_xlabel("Time (ms)") ax1.set_ylabel("Max position (mm)") ax1.set_ylim(0, z0_mm) # 位置转频率的正向转换,替换为你实际的转换公式 def pos_to_freq(pos): return fion_kHz * (1 + pos / z0_mm * (f_shift4 + f_shift6) / 100) # 频率转位置的反向转换,和上面的公式对应即可 def freq_to_pos(freq): return (freq / fion_kHz - 1) * z0_mm * 100 / (f_shift4 + f_shift6) # 新增右侧频率次Y轴 ax2 = ax1.secondary_yaxis('right', functions=(pos_to_freq, freq_to_pos)) ax2.set_ylabel("Oscillation frequency (kHz)") # 若需要叠加频率曲线,先将频率值转为位置单位后用主坐标轴绘制即可 # pos_from_freq = freq_to_pos(frequency_axis) # ax1.plot(time_max_axis, pos_from_freq, color='orange', label='频率曲线') # ax1.legend() plt.show()
注意事项
- 反向转换函数必须定义,即使你不会主动调用,matplotlib计算刻度位置时需要依赖该函数
- 无需手动设置
yticks,该接口在缩放、平移画布时会自动同步更新次轴刻度,不会出现刻度挤在一起的问题 - 如需添加多个次坐标轴,多次调用
secondary_yaxis,调整location参数设置不同偏移量即可实现多轴叠加
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

