I am currently trying several methods to fit and afterwards transform some data using a 2nd degree polynomial function. I have been using the following code to that end:
import matplotlib.pyplot as plt
import numpy
from scipy.optimize import curve_fit
def fitFunc(self, x,a,b,c):
return a*x**2 + b*x + c
def calcQuadratic(self,data):
""" This function fits the specified function in 'fitFunc'
to the data, using the curve_fit package from scipy.optimize.
INPUT: A list of (m/z,int) tuples
OUTPUT: The parameters for the fitted function
"""
expected = []
observed = []
for i in data:
expected.append(i[0])
observed.append(i[1])
z = curve_fit(self.fitFunc, observed, expected)
#############
# Plot Code #
#############
newX = numpy.linspace(0,400,2500)
yNew = self.fitFunc(newX,*z[0])
fig = plt.figure()
ax = fig.add_subplot(111)
plt.scatter(expected,observed,label='raw')
plt.plot(newX,yNew,label='obs-exp')
plt.legend()
plt.show()
###############
# end of plot #
###############
return z[0]
Subsequently I transform the data by doing basically:
new = []
for i in data:
new.append((fitFunc(i[0],*z[0]),i[1]))
Problem
The above transformation can result in my Y-intercept having a positive X-value. The result of that is that after the transformation, I have data that is now found at the same value (see the picture below)
The data points connected by the purple line are examples of problem cases, data observed at ~5 seconds and ~110 seconds would be forced to a time of ~100 seconds after transformation.
Question
Therefore, I would like to know if there is a way to force the function maximum (or minimum) to X = 0? I am also open to other suggestions to bypass this problem (currently, I am ignoring the left half of the polynomial as a temporary dirty hack/fix).
Additional information
Removing the b*x
part of the fit function is not a possibility as this function should be able to return a (near) linear fit as well, see the below plot