Python matplotlib对数y轴非线性网格设置及BER曲线拟合咨询
问题1:实现对数刻度下非线性分布的y轴网格线
你已经完成了y轴对数刻度的设置,默认的grid=True仅会显示10的整数次幂位置的主网格线,要实现参考图中细密的非线性次网格,只需额外自定义主次网格的显示规则即可,将你代码中dfLTLV.plot里的grid=True删除,在设置y轴对数刻度的代码后添加以下内容:
# 配置y轴主网格线(10的整数次幂刻度位置,线条更粗) axes.grid(which='major', axis='y', linestyle='-', linewidth=0.8, color='#666666') # 配置y轴次网格线(两个相邻10次幂之间的1~9中间刻度位置,线条更细,就是你需要的非线性分布网格) axes.grid(which='minor', axis='y', linestyle='--', linewidth=0.4, color='#cccccc')
对数刻度下次网格的位置本身就是非线性分布的,上述配置即可实现和参考图完全一致的网格效果。
问题2:BER瀑布曲线的拟合函数实现
这类光通信领域的误码率(BER)随接收功率/OSNR变化的瀑布曲线,通常采用Q函数(高斯互补累积分布函数)进行拟合,符合物理层传输的误码规律,具体实现步骤如下:
- 先导入依赖库:
import numpy as np from scipy.optimize import curve_fit from scipy.special import erfc
- 定义拟合函数,BER和接收功率的关系为:
def ber_waterfall_fit(x, a, b): # x为接收功率/OSNR值,a、b为待拟合参数 Q = a * x + b return 0.5 * erfc(Q / np.sqrt(2))
- 提取有效数据执行拟合,并将拟合曲线绘制到图中:
# 过滤掉BER为0的无效数据,避免对数拟合报错 x_data = dfLTLV['RxPower_dBm'].values y_data = dfLTLV['BerMeasurement'].values valid_mask = y_data > 0 x_valid = x_data[valid_mask] y_valid = y_data[valid_mask] # 执行拟合,p0为参数初始猜测值,可根据你的数据范围调整避免拟合发散 popt, _ = curve_fit(ber_waterfall_fit, x_valid, y_valid, p0=[1, 30], maxfev=10000) # 生成拟合曲线的采样点并绘制 x_fit = np.linspace(-35, -24, 100) y_fit = ber_waterfall_fit(x_fit, *popt) axes.plot(x_fit, y_fit, linestyle='-', linewidth=linewidth1, label='拟合曲线') # 别忘了更新图例显示拟合曲线 axes.legend(loc='center', bbox_to_anchor=(1.15, 0.5),fontsize=12)
学习路径推荐
- 绘图部分:重点学习matplotlib的刻度控制相关接口,掌握
which参数区分主次刻度、对数轴配置的用法,可参考官方文档中轴配置板块的内容 - 拟合部分:先了解光通信BER的基础物理模型,再学习scipy的
curve_fit非线性最小二乘拟合的使用方法,理解参数初始值对拟合结果的影响即可快速掌握这类场景的拟合操作
内容的提问来源于stack exchange,提问作者liaquat85
相关产品推荐
相关产品推荐

