使用Matplotlib与Scipy进行二次曲线拟合失效问题求助
二次拟合曲线视觉不符合预期的问题解决
问题根源分析
- 拟合函数与数据趋势不匹配:你的y值(1,4,12,29,54,104)增长速度远超二次函数的增长规律,更接近三次函数的增长特征,强行用二次拟合会导致效果偏差。
- 拟合线绘制不连续:代码中
x_line = arange(min(x), max(x), 1)只取了整数x值,绘制出的是折线而非平滑的二次曲线,视觉上不符合预期。 - 冗余代码干扰:加载longley数据集的代码完全未使用,属于无效代码,建议删除。
解决方案1:改用三次函数拟合(匹配数据增长趋势)
修改拟合函数为三次多项式,同时优化拟合线的平滑度:
import numpy as np from numpy import arange from scipy.optimize import curve_fit from matplotlib import pyplot x = np.array([1,2,3,4,5,6]) y = np.array([1,4,12,29,54,104]) # 定义三次拟合函数 def objective(x, a, b, c, d): return a * x**3 + b * x**2 + c * x + d # 执行曲线拟合 popt, _ = curve_fit(objective, x, y) a, b, c, d = popt print('y = %.5f * x^3 + %.5f * x^2 + %.5f * x + %.5f' % (a, b, c, d)) # 绘制原始数据散点图 pyplot.scatter(x, y) # 生成密集x值,确保拟合线平滑 x_line = arange(min(x), max(x)+0.1, 0.1) # 计算拟合曲线的y值 y_line = objective(x_line, a, b, c, d) # 绘制平滑拟合线 pyplot.plot(x_line, y_line, '--', color='red') pyplot.show()
解决方案2:优化二次拟合的可视化效果(若坚持用二次函数)
如果必须使用二次拟合,只需调整x值的密度,让拟合线呈现平滑的二次曲线形态:
import numpy as np from numpy import arange from scipy.optimize import curve_fit from matplotlib import pyplot x = np.array([1,2,3,4,5,6]) y = np.array([1,4,12,29,54,104]) # 二次拟合函数 def objective(x, a, b, c): return a * x + b * x**2 + c # 执行曲线拟合 popt, _ = curve_fit(objective, x, y) a, b, c = popt print('y = %.5f * x + %.5f * x^2 + %.5f' % (a, b, c)) # 绘制原始数据散点图 pyplot.scatter(x, y) # 生成密集x值,替代原有的整数步长 x_line = arange(min(x), max(x)+0.1, 0.1) # 计算拟合曲线的y值 y_line = objective(x_line, a, b, c) # 绘制平滑的二次拟合线 pyplot.plot(x_line, y_line, '--', color='red') pyplot.show()
补充说明
- 二次函数对当前数据的拟合误差会较大,因为数据的二阶差分是递增的,这是三次函数的特征。
- 绘制拟合曲线时,务必使用足够密集的x值,才能直观呈现多项式曲线的形态。
内容的提问来源于stack exchange,提问作者Ondřej Skála
相关产品推荐
相关产品推荐

