2017-02-27 110 views
0

我目前正在試圖在MatPlotLib中繪製散點圖上的趨勢線圖。如何在基於KDE的散點圖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

趨勢可以很容易看到,但問題是w帽子功能使用?

+0

您能添加一個有代表性的數據集和預期結果的圖片嗎? – Nilesh

+0

我的數據集大約是0.5 Gb,我該如何取代它? –

+0

對我來說''polyfit'似乎適合在這種情況下使用。也許這會有助於說明你沒有使用它的原因。當然還有其他的工具可以用來適應數據,statsmodel包中最簡單的工具是[普通最小二乘](http://statsmodels.sourceforge.net/devel/regression.html)。另外你正在使用的工具(你沒有告訴它是哪一個)可能有一個可用。你也可以簡單地使用['seaborn.regplot'](http://seaborn.pydata.org/generated/seaborn.regplot.html),其缺點是你沒有得到任何關於你的適合性的信息。 – ImportanceOfBeingErnest

回答

0

樣本[0]是您的「y」,樣本[1]是您的「x」。在趨勢線圖中使用樣本[1]。

+0

我已經試過了,它也顯示了錯誤的趨勢 –

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() 
+0

這是一個很好的答案,即使它沒有解釋我,如何使我想要的適合=) –

+0

你真的想要歐幾里得距離最小化呢?你的觀點代表什麼?你想從健康中學到什麼? – Jannick

+0

這是從地震數據中提取的截距和梯度。如果我能設法使其符合我的趨勢 - 我將有一個流體線方程,我需要進一步分析 –