Using orthogonal least squares instead of polyfit gives the desired answer. There is a built in package for this within scipy.
from scipy import odr
def linear_func(p, x):
m, c = p
return m*x + c
#Create a Model.:
linear = odr.Model(linear_func)
#Create a Data or RealData instance.:
mydata = odr.Data(xArray, yArray)
#or, when the actual covariances are known:
mydata = odr.RealData(x, y, sx=sx, sy=sy)
#Instantiate ODR with your data, model and initial parameter estimate.:
myodr = odr.ODR(mydata, linear, beta0=[1., 2.])
#Run the fit.:
myoutput = myodr.run()
#Examine output.:
myoutput.pprint()
Instead of vertical distance to each point, this method uses perpendicular distance as shown above. This gives better fits for when your data has a strong down or up trend.
There are more detailed explanations on how to use this method here.
referece: documentation
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…