如何在基于KDE的散点图matplotlib上绘制趋势线?

时间:2017-02-27 21:28:14

标签: python matplotlib

我目前正在尝试在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)

结果如下:

Scatter-plot with trends

我想要的是:

Scatter-Plot_desired

趋势很容易看出,但问题是使用什么功能?

2 个答案:

答案 0 :(得分:0)

样品[0]是你的" y"和样本[1]是你的" x"。在趋势线图中使用样本[1]。

答案 1 :(得分:0)

polyfit的行为是例外,结果是正确的。问题是polyfit没有做到,你期望的是什么。所有(典型的)拟合程序最小化拟合和要拟合的数据点之间的垂直(y轴)距离。然而,您似乎期望它最小化拟合和数据之间的欧氏距离。看看这个图中的差异: enter image description here

此处还可以看到用随机数据说明事实的代码。注意,数据(参数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()