**Important:** Widgets will not display in "static" notebooks until IPython 3.0. They must be backed by a live IPython kernel. Therefore, to view the full widget display, you must download this notebook and run it locally using IPython 2.x or greater.

In [1]:

```
%matplotlib inline
from lmfit import Model, Fitter
import numpy as np
```

`lmfit`

¶The lmfit package provides layers of high-level interfaces to the nonlinear optimization and curve fitting algorithms in scipy.

`Parameter`

objects allow fit parameters to be bounded (`min`

,`max`

) or held fixed (`vary=False`

).- The
`Model`

class provides a general way to wrap a user-defined function as a fitting model. `Fitter`

provides a curve-fitting workflow akin to popular GUI-based tools while retaining programmatic access to the underlying objects.

`BaseFitter`

introduces no new dependencies; `MPLFitter`

requires matplotlib; `NotebookFitter`

uses IPython's rich display to represent each `Parameter`

as a group of IPython widgets. `Fitter`

will point to the richest implementation available.

Select any model from the drop-down menu.

Text input widgets will appear corresponding to the parameters for that model. If the model supports automatic guessing, the values will be initialized according to `model.guess(data, ...)`

, and an auto-guess button will be available to re-generate these values at any time.

The values in the text input widgets will serve as an initial guess, and they can be edited by the user. Text inputs for `min`

and `max`

appear when the associated checkboxes are checked. At all times, `fitter.current_params`

is maintained in sync with the values shown in the widget.

When satisfied with the initial guess, click "Fit". The plot will update to show the data, the initial guess fit (gray), and the best fit (red). The attribute `fitter.current_result`

will contain the result object created by the latest execution of `fit`

. The text widgets and the property `fitter.current_params`

will be updated from the initial fit to the latest best fit.

In [2]:

```
data = np.array([1,2,3,4,5,4,3,2])
x = np.arange(len(data))
fitter = Fitter(data, x=x)
fitter
```

In [3]:

```
fitter.current_result.values
```

Out[3]:

{'amplitude': 26.028242079115383, 'center': 3.9949292338671754, 'fwhm': 5.2960363977622071, 'sigma': 2.2490196268768767}

Unlike `Model`

, `Fitter`

is "stateful;" it remembers that it has been called, and it uses each best fit as the initial guess for the next fit (unless a new guess is provided).

Execute the cell below and revisit to the fitter above. (Or create a new view below; multiple views of the same instance of `fitter`

all stay in sync.) Clicking "Fit" will use the most recent best fit to `data`

as the initial guesss for fitting `other_data`

.

In [4]:

```
other_data = np.array([10, 11, 12, 11, 10, 8, 7, 6])
fitter.data = other_data
```

Any subclass of `Model`

will be included in the drop-down menu. Look for 'UserDefinedModel' in the menu below.

In [5]:

```
def func(x, a=1):
"a very simple model indeed"
return x + a
class UserDefinedModel(Model):
def __init__(self, *args, **kwargs):
super(UserDefinedModel, self).__init__(func, *args, **kwargs)
```

In [6]:

```
data = np.array([1,2,3,4,5,4,3,2])
x = np.arange(len(data))
fitter = Fitter(data, x=x)
fitter
```

See the docstring for more, including complete access to the plot elements.