I have data of the form shown in figure. The natural logarithm of the data when will always have three distinct linear ranges but the ranges will not always be the same, it varies with data, but there will definitely be three regions where three different linear fits can be made.
I am trying to determine the best three linear fits to natural logarithm of it marked as I, II and III. The figure shows natural logarithm of y-data. This has to applied to at least thousand datasets. The code automatically has to detect the best linear fits for the three regions shown in figure.
I am trying to get it done using thus code which tries to apply two piecewise linear fits using code from here, but it does not correctly. I need it extended to three liner fits. How can I determine three best linear fits to the data with Python?
MWE
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.colors as colors
import matplotlib.cm as mplcm
import itertools
from scipy import optimize
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])
with open('./three_piecewise_linear.dat', "r") as data:
while True:
line = data.readline()
if not line.startswith('#'):
break
data_header = [i for i in line.strip().split('\t') if i]
_data_ = np.genfromtxt(data, names = data_header, dtype = None, delimiter = '\t')
_data_.dtype.names = [j.replace('_', ' ') for j in _data_.dtype.names]
data = np.array(_data_.tolist())
n_rf = data.shape[1] - 2
xd = np.linspace(1, 1.5, 100)
fit_data = np.empty(shape = (100, n_rf))
for i in range(n_rf):
p , e = optimize.curve_fit(piecewise_linear, data[:, 1], np.log(data[:, i + 2]))
fit_data[:, i] = piecewise_linear(xd, *p)