我目前正在尝试在MatPlotLib中的散点图上绘制趋势线图。
我知道numpy polyfit
函数。它没有做我想做的事。
所以我到目前为止:
plot = plt.figure(figsize=(10,10)) #Set up the size of the figure
cmap = "viridis" #Set up the color map
plt.scatter(samples[1], samples[0], s=0.1, c=density_sm, cmap=cmap) #Plot the Cross-Plot
plt.colorbar().set_label('Density of points')
plt.axis('scaled')
plt.xlim(-0.3,0.3)
plt.ylim(-0.3,0.3)
plt.xlabel("Intercept")
plt.ylabel("Gradient")
plt.axhline(0, color='green', alpha=0.5, linestyle="--")
plt.axvline(0, color='green', alpha=0.5, linestyle="--")
#Trend-line_1
z = np.polyfit(samples[1], samples[0], 1)
p = np.poly1d(z)
plt.plot(samples[0],p(samples[0]),color="#CC3333", linewidth=0.5)
#Trend-line_2
reg = sm.WLS(samples[0], samples[1]).fit()
plt.plot(samples[1], reg.fittedvalues)
结果如下:
我想要的是:
趋势很容易看出,但问题是使用什么功能?
答案 0 :(得分:0)
样品[0]是你的" y"和样本[1]是你的" x"。在趋势线图中使用样本[1]。
答案 1 :(得分:0)
polyfit的行为是例外,结果是正确的。问题是polyfit没有做到,你期望的是什么。所有(典型的)拟合程序最小化拟合和要拟合的数据点之间的垂直(y轴)距离。然而,您似乎期望它最小化拟合和数据之间的欧氏距离。看看这个图中的差异:
此处还可以看到用随机数据说明事实的代码。注意,数据(参数a)的线性关系通过拟合来恢复,而欧几里德拟合则不是这种情况。因此,首选看似不合适。
N = 10000
a = -1
b = 0.1
datax = 0.3*b*np.random.randn(N)
datay = a*datax+b*np.random.randn(N)
plot = plt.figure(1,figsize=(10,10)) #Set up the size of the figure
plot.clf()
plt.scatter(datax,datay) #Plot the Cross-Plot
popt = np.polyfit(datax,datay,1)
print("Result is {0:1.2f} and should be {1:1.2f}".format(popt[-2],a))
xplot = np.linspace(-1,1,1000)
def pol(x,popt):
popt = popt[::-1]
res = 0
for i,p in enumerate(popt):
res += p*x**i
return res
plt.plot(xplot,pol(xplot,popt))
plt.xlim(-0.3,0.3)
plt.ylim(-0.3,0.3)
plt.xlabel("Intercept")
plt.ylabel("Gradient")
plt.tight_layout()
plt.show()