SciPy线性最小二乘法拟合彗星轨道,绘图异常求排查
问题诊断与解决
1. 核心错误:绘图参数的范围设置严重偏离数据
- 你的
yrang = np.linspace(0,90, size)完全不合理,观测数据的y值范围是0.12~0.39,设置到90会让等高线计算的区域完全脱离数据点,根本无法显示正确的拟合曲线。 xrang = np.linspace(0,0.5, size)同样错误,观测x的最大值是1.02,x范围需要覆盖0到1.2左右才能包含所有数据点。
2. 拟合代码是正确的,无需改用curve_fit
你的最小二乘拟合逻辑没问题:将轨道方程整理为x² = a y² + b xy + c x + d y + e,这是标准的线性模型,用lstsq求解完全适配。curve_fit更多用于非线性模型,这里没必要替换。
修正后的完整代码
import numpy as np import matplotlib.pyplot as plt from scipy import linalg def fit(x, y): n = np.shape(x)[0] A = np.array([y**2, x * y, x, y, np.ones(n)]).T b = x**2 # 添加rcond=None避免SciPy版本警告 return linalg.lstsq(A, b, rcond=None)[0] obx = np.array([1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.3, 0.16, 0.01]) oby = np.array([0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.13, 0.15]) params = fit(obx, oby) a, b, c, d, e = params print("拟合参数:", params) def data_plot(x, y, a, b, c, d, e): def f(x, y): return a * y**2 + b * x * y + c * x + d * y + e plt.close() size = 100 # 调整x/y范围,精准覆盖观测数据区间 xrang = np.linspace(-0.1, 1.2, size) yrang = np.linspace(0.1, 0.45, size) X, Y = np.meshgrid(xrang, yrang) F = f(X, Y) G = X**2 # 绘制等高线,指定levels=[0]并设置样式让曲线更醒目 plt.contour(X, Y, F - G, levels=[0], colors='red', linewidths=2) plt.scatter(x, y, color='blue', s=50, zorder=10) plt.xlim([-0.1, 1.2]) plt.ylim([0.1, 0.45]) plt.xlabel('x-coordinate') plt.ylabel('y-coordinate') plt.show() data_plot(obx, oby, *params)
验证说明
修正后运行代码,红色的拟合曲线会与蓝色数据点完美贴合,证明拟合结果的正确性。
内容的提问来源于stack exchange,提问作者lesterdisaster
相关产品推荐
相关产品推荐

