我正在尝试将二阶多项式拟合到原始数据并使用Matplotlib输出结果。我试图适应的数据集中有大约一百万个点。它应该很简单,网上有很多例子。但由于某些原因,我无法做到正确。
我收到以下警告信息:
RankWarning:Polyfit的条件很差
这是我的输出:
使用Excel输出:
请参阅下面的代码。我错过了什么?
xData = df['X']
yData = df['Y']
xTitle = 'X'
yTitle = 'Y'
title = ''
minX = 100
maxX = 300
minY = 500
maxY = 2200
title_font = {'fontname':'Arial', 'size':'30', 'color':'black', 'weight':'normal',
'verticalalignment':'bottom'} # Bottom vertical alignment for more space
axis_font = {'fontname':'Arial', 'size':'18'}
#Poly fit
# calculate polynomial
z = np.polyfit(xData, yData, 2)
f = np.poly1d(z)
print(f)
# calculate new x's and y's
x_new = xData
y_new = f(x_new)
#Plot
plt.scatter(xData, yData,c='#002776',edgecolors='none')
plt.plot(x_new,y_new,c='#C60C30')
plt.ylim([minY,maxY])
plt.xlim([minX,maxX])
plt.xlabel(xTitle,**axis_font)
plt.ylabel(yTitle,**axis_font)
plt.title(title,**title_font)
plt.show()
答案 0 :(得分:3)
必须对要绘制的数组进行排序。以下是绘制已排序和未排序数组之间的比较。未分类情况下的情节看起来完全失真,但是,拟合函数当然是相同的。
2
-3.496 x + 2.18 x + 17.26
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = (np.random.normal(size=300)+1)
fo = lambda x: -3*x**2+ 1.*x +20.
f = lambda x: fo(x) + (np.random.normal(size=len(x))-0.5)*4
y = f(x)
fig, (ax, ax2) = plt.subplots(1,2, figsize=(6,3))
ax.scatter(x,y)
ax2.scatter(x,y)
def fit(ax, x,y, sort=True):
z = np.polyfit(x, y, 2)
fit = np.poly1d(z)
print(fit)
ax.set_title("unsorted")
if sort:
x = np.sort(x)
ax.set_title("sorted")
ax.plot(x, fo(x), label="original func", color="k", alpha=0.6)
ax.plot(x, fit(x), label="fit func", color="C3", alpha=1, lw=2.5 )
ax.legend()
fit(ax, x,y, sort=False)
fit(ax2, x,y, sort=True)
plt.show()
答案 1 :(得分:0)
问题可能是使用功率基础来计算沿x轴从零移位一定距离的数据。如果您使用Polynomial
中的numpy.polynomial
类,它将在拟合之前缩放和移位数据,这将有所帮助,并且还会跟踪所使用的比例和移位。请注意,如果您希望系数处于正常形式,则需要转换为该形式。