Search code examples
pythonnumpymatplotliblmfit

With using lmfit module in python, how to call the parameters in the model?


import numpy as np

import matplotlib.pyplot as plt

from lmfit import minimize, Parameters, Parameter, report_fit


# create data to be fitted


x = np.linspace(0, 15, 301)

data = (5. * np.sin(2 * x - 0.1) * np.exp(-x*x*0.025) +

np.random.normal(size=len(x), scale=0.2) )

# define objective function: returns the array to be minimized


def fcn2min(params, x, data):

    """ model decaying sine wave, subtract data"""
    amp = params['amp'].value
    shift = params['shift'].value
    omega = params['omega'].value
    decay = params['decay'].value
    model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)


    return model - data


# create a set of Parameters

params = Parameters()

params.add('amp',   value= 10,  min=0)

params.add('decay', value= 0.1)

params.add('shift', value= 0.0, min=-np.pi/2., max=np.pi/2)

params.add('omega', value= 5.0)


# do fit, here with leastsq model

result = minimize(fcn2min, params, args=(x, data))


# calculate final result

final = data + result.residual


# try to plot results
plt.plot(x,data,'k+')

plt.plot(x,final,'r')

plt.show()

In this code, I want to call the parameters like 'amp', 'shift' in the python. Print(amp).. kinds of things How to call these parameters in the python after fitting? When I use print(amp), the error message is shown; name 'amp' is not defined. How to print these fitted parameters using print function? (etc. print(amp))


Solution

  • You are likely trying to print that data outside of the function. The amp, shift, omega and decay variables are in fc2min's local scope and are therefore only accessible inside the function. Your data analysis skills seem to far outmatch your Python know-how, so I added some helpful tips inside this code:

    import numpy as np
    import matplotlib.pyplot as plt
    from lmfit import minimize, Parameters, Parameter, report_fit
    
    # create data to be fitted
    x = np.linspace(0, 15, 301)
    data = (5. * np.sin(2 * x - 0.1) * np.exp(-x*x*0.025) +
    np.random.normal(size=len(x), scale=0.2) )
    
    # define objective function: returns the array to be minimized
    def fcn2min(params, x, data):
    
        """ model decaying sine wave, subtract data"""
        amp = params['amp'].value
        shift = params['shift'].value
        omega = params['omega'].value
        decay = params['decay'].value
        model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
    
        # tell Python we're modifying the model_data list
        # that was declared outside of this function
        global model_data
    
        # store the model data produced by this function call
        # add any data you want to display later to this "dictionary"
        model_data += [{
            "amp": amp,
            "shift": shift,
            "omega": omega,
            "decay": decay
        }]
    
        return model - data
    
    
    # create a set of Parameters
    params = Parameters()
    params.add('amp',   value= 10,  min=0)
    params.add('decay', value= 0.1)
    params.add('shift', value= 0.0, min=-np.pi/2., max=np.pi/2)
    params.add('omega', value= 5.0)
    
    # declare an empty list to hold the model data
    model_data = []
    
    # do fit, here with leastsq model
    result = minimize(fcn2min, params, args=(x, data))
    
    # print each item in the model data list
    for datum in model_data:
        for key in datum:
    
            #the 5 in %.5f controls the precision of the floating point value
            print("%s: %.5f  ") % (key, datum[key]),
        print
    
    
    # calculate final result
    final = data + result.residual
    
    # try to plot results
    plt.plot(x,data,'k+')
    plt.plot(x,final,'r')
    plt.show()