如何在Python的半对数图(Semilogy Plot)中实现多项式拟合
半对数图(Semilogy Plot)中的多项式拟合方案
我来帮你搞定这个半对数图的拟合问题!你之前用numpy.polyfit在双对数图里做拟合的思路其实可以迁移过来,核心是搞清楚半对数坐标系对应的函数转换关系,下面给你两种实用的实现方法:
核心逻辑说明
半对数图(semilogy)是y轴取对数、x轴保持线性的坐标系。如果希望在这个图里拟合出多项式曲线,本质上是对**原始x值(你的l)和log(f)**做多项式拟合,然后再把拟合结果转换回原坐标系(也就是对拟合的多项式结果取指数)。
方法一:用numpy.polyfit快速实现
这种方法最直接,和你之前双对数拟合的思路一致,只是拟合的变量换成了x和log(y):
import matplotlib.pyplot as plt import numpy as np # 你的原始数据 l = [0.006, 0.01, 0.014, 0.024, 0.0346, 0.049, 0.0535, 0.0736, 0.11] # 补全你省略的f数据(确保所有值为正数,否则取对数会报错) f = [5.337590338333005, 60.53197642251305, 89.11150252613147, 47.13249850158497, 17.447001, 8.215, 6.98, 3.12, 1.05] # 1. 选择多项式次数(比如2次,可根据需求调整) poly_degree = 2 # 2. 对f取自然对数(也可以用np.log10,只要前后一致就行) log_f = np.log(f) # 3. 拟合x(l)和log(f),得到多项式系数 coeffs = np.polyfit(l, log_f, poly_degree) poly_func = np.poly1d(coeffs) # 生成多项式对象,方便计算 # 4. 生成密集的x值用于绘制拟合曲线 x_fit = np.linspace(min(l), max(l), 100) # 计算拟合的f值:先算log(f)的拟合值,再指数化回到原坐标系 f_fit = np.exp(poly_func(x_fit)) # 5. 绘制半对数图 plt.figure(figsize=(10,6)) plt.semilogy(l, f, 'o', label='原始数据点') plt.semilogy(x_fit, f_fit, '-', linewidth=2, label=f'{poly_degree}次多项式拟合') plt.xlabel('l') plt.ylabel('f') plt.title('半对数图中的多项式拟合(polyfit实现)') plt.legend() plt.grid(True, which="both", ls="-") # 显示网格,方便观察 plt.show()
方法二:用scipy.curve_fit自定义拟合函数
如果需要更灵活的拟合形式(比如加入约束条件),可以用curve_fit直接拟合指数多项式形式的函数(对应半对数图里的多项式曲线):
import matplotlib.pyplot as plt import numpy as np from scipy.optimize import curve_fit # 原始数据同上 l = [0.006, 0.01, 0.014, 0.024, 0.0346, 0.049, 0.0535, 0.0736, 0.11] f = [5.337590338333005, 60.53197642251305, 89.11150252613147, 47.13249850158497, 17.447001, 8.215, 6.98, 3.12, 1.05] # 1. 定义指数多项式拟合函数(这里以2次为例) def exp_poly(x, a, b, c): # 对应半对数图里的二次多项式:log(f) = a*x² + b*x + c → f = exp(a*x² + b*x + c) return np.exp(a * x**2 + b * x + c) # 2. 初始参数猜测(可以用方法一的polyfit结果作为初始值,提高拟合成功率) initial_guess = np.polyfit(l, np.log(f), 2) # 3. 执行拟合 popt, pcov = curve_fit(exp_poly, l, f, p0=initial_guess) # 4. 生成拟合曲线 x_fit = np.linspace(min(l), max(l), 100) f_fit = exp_poly(x_fit, *popt) # 5. 绘图 plt.figure(figsize=(10,6)) plt.semilogy(l, f, 'o', label='原始数据点') plt.semilogy(x_fit, f_fit, '--', linewidth=2, label='指数多项式拟合(curve_fit实现)') plt.xlabel('l') plt.ylabel('f') plt.title('半对数图中的多项式拟合(curve_fit实现)') plt.legend() plt.grid(True, which="both", ls="-") plt.show()
注意事项
- 确保你的
f数据全为正数,否则取对数会抛出错误; - 多项式次数可以根据数据的实际分布调整,次数过高容易出现过拟合;
- 如果只需要在半对数图里拟合直线(对应原数据的指数函数),把多项式次数设为1即可,此时拟合函数为
f = exp(b*x + c)。
内容的提问来源于stack exchange,提问作者bhjghjh
相关产品推荐
相关产品推荐

