I am fairly new to python and I am trying to do some curve fitting using lmfit. The code works pretty well but I would like to force the fit through the origin (0,0). I've seen here in stakoverlow that using "curve_fit" you can add and attribute "sigma" that does the trick but this does not work in "minimize". Do you have any workaround to this???
So far, this is my code:
##############################################################################
###################### IMPORT MODULES ########################################
##############################################################################
import numpy as np
import matplotlib.pyplot as plt
from lmfit import minimize, Parameters
from lmfit import report_fit
##############################################################################
##################### DATA ##################################
##############################################################################
x=np.array([0,1, 4, 6, 8, 9, 11, 13, 15, 18, 20, 27])
data=np.array([0, 67, 208, 339, 460, 539, 599, 635, 659, 685, 701, 731])
##############################################################################
######################## GOMPERTZ FUNCTION DEFINITION#########################
##############################################################################
def BMP_Gompertz(params, x, data):
BMPmax=params['BMPmax'].value
Rmax=params['Rmax'].value
Lambda=params['Lambda'].value
model=BMPmax*np.exp(-np.exp(Rmax*np.exp(1)/BMPmax*(Lambda-x)+1))
global model_data
model_data=[BMPmax,Rmax,Lambda]
return data-model
params=Parameters()
params.add('BMPmax', value=300., min=0.)
params.add('Rmax', value=25., min=0.)
params.add('Lambda',value=0.5, min=0.)
model_data=[]
##############################################################################
###################### GOMPERTZ CURVE FITTING & REPORT #######################
##############################################################################
result=minimize(BMP_Gompertz, params, args=(x,data))
report_fit(result.params)
##############################################################################
########################## GOMPERTZ PLOTTING #################################
##############################################################################
plt.plot(x, data, 'bo')
t=np.linspace(0.,100,10000)
plt.plot(t,model_data[0]*np.exp(-np.exp(model_data[1]*np.exp(1)/model_data[0]*(model_data[2]-t)+1)))
plt.xlabel('Days')
plt.ylabel('BMP (NLbiogas/kg SV)')
plt.show()
as you can seee, the fit does not start at (0,0) but at around (0,10) and I would like to always force it to start at (0,0)... It looks like I am still not able to upload images (don't have persmissions yet)... anyway, I think you can get the point.
Also another question, is there another way to store the parameters and plot the results?. Right now to store the the parameters returned by the model I am doing it by storing them ina global variable called "model_data". Then, in the plot section I've created a new "x" array called "t" using linspace and then plotting the t vs BMP_Gompertz (myfunction) using the parameters stored in "model_data". Works perfectly, but it looks like it should be other nicer ways to do that.
Thank you very much for your help