numpy - How to apply piecewise linear fit in Python? -
i trying fit piecewise linear fit shown in fig.1 data set
this figure obtained setting on lines. attempted apply piecewise linear fit using code:
from scipy import optimize import matplotlib.pyplot plt import numpy np x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15]) y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03]) def linear_fit(x, a, b): return * x + b fit_a, fit_b = optimize.curve_fit(linear_fit, x[0:5], y[0:5])[0] y_fit = fit_a * x[0:7] + fit_b fit_a, fit_b = optimize.curve_fit(linear_fit, x[6:14], y[6:14])[0] y_fit = np.append(y_fit, fit_a * x[6:14] + fit_b) figure = plt.figure(figsize=(5.15, 5.15)) figure.clf() plot = plt.subplot(111) ax1 = plt.gca() plot.plot(x, y, linestyle = '', linewidth = 0.25, markeredgecolor='none', marker = 'o', label = r'\textit{y_a}') plot.plot(x, y_fit, linestyle = ':', linewidth = 0.25, markeredgecolor='none', marker = '', label = r'\textit{y_b}') plot.set_ylabel('y', labelpad = 6) plot.set_xlabel('x', labelpad = 6) figure.savefig('test.pdf', box_inches='tight') plt.close()
but gave me fitting of form in fig. 2, tried playing values no change can't fit of upper line proper. important requirement me how can python gradient change point. in essence i want python recognize , fit 2 linear fits in appropriate range. how can done in python?
you can use numpy.piecewise()
create piecewise function , use curve_fit()
, here code
from scipy import optimize import matplotlib.pyplot plt import numpy np %matplotlib inline x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15], dtype=float) y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03]) def piecewise_linear(x, x0, y0, k1, k2): return np.piecewise(x, [x < x0], [lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0]) p , e = optimize.curve_fit(piecewise_linear, x, y) xd = np.linspace(0, 15, 100) plt.plot(x, y, "o") plt.plot(xd, piecewise_linear(xd, *p))
the output:
Comments
Post a Comment