If you want to fit data with a polynomial, but you want certain data points to pass through, here's an easy way to do it.
When using numpy's polyfit, you can specify the weight with the option w, so increase the weight of the point you want to fix. Here is an example where the data does not pass through the origin, but you want to force it through the origin when fitting. Data is added to the original data x, y with te, numpy.append, the weight of that point is set to 1e3, and the others are set to 1.
qiita_polyfit_limited.py
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
x = np.array([-10, -8,-6,-4,-2,0,2,4,6,8,10])
y = np.array([-15,-10,-3,-2,-1,3,1,3,4,8,12])
weight = np.ones(len(x))
npoly=4
x_add = np.append(x,0)
y_add = np.append(y,0)
weight_add = np.append(weight,1e3)
coef=np.polyfit(x, y, npoly, w=weight)
yfit = np.poly1d(coef)(x)
coef_add=np.polyfit(x_add, y_add, npoly, w=weight_add)
yfit_add = np.poly1d(coef_add)(x)
F = plt.figure(figsize=(7,7))
ax = plt.subplot(1,1,1)
plt.errorbar(x,y,fmt="o",label="data",alpha=0.8,ms=3)
plt.errorbar(x,yfit,fmt="--",label="fit (no limit), order = " +str(npoly),alpha=0.8,ms=3)
plt.errorbar(x,yfit_add,fmt="--",label="fit (fixed at 0,0), order = " +str(npoly),alpha=0.8,ms=3)
plt.grid(linestyle='dotted',alpha=0.5)
plt.legend(numpoints=1, frameon=False, loc="best")
outfile = "qiita_polyfitlimited.png "
plt.savefig(outfile)
If you do not limit anything, it will not pass through the origin, but if it is restricted, you can see that it has passed through the origin.
Since it is not a strict conditional fit, a small value remains, not zero, at the origin. If you want to be exactly 0 at the origin, you have to write the restricted fit function yourself. In that case, How to do fitting with parameter restrictions in python Please refer to.
Recommended Posts