<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 PyBroom Example - Simple
This notebook is part of pybroom.
This notebook shows the simplest usage of pybroom when performing
a curve fit of a single dataset. Possible applications are only hinted.
For a more complex (and interesting!) example using multiple datasets see
pybroom-example-multi-datasets.
Step1:  Create Noisy Data
Step2:  Model Fitting
Step3:  Fit result from an lmfit Model can be inspected with
with fit_report or params.pretty_print()
Step4:  These methods a re convenient but extracting the data
from the lmfit object requires some work and the knowledge
of lmfit object structure.
pybroom comes to help, extracting data from fit results and
returning  pandas DataFrame in tidy format that can be 
much more easily manipulated, filtered and plotted.
Glance
Glancing at the fit results (dropping some verbose columns)
Step5:  The glance 
function returns a DataFrame with one row per fit-result object.
Application Idea
If you fit N models to the same dataset
you can compare statistics such as reduced-$\chi^2$
Or, fitting several with several methods (and datasets) you
can study the convergence properties using reduced-$\chi^2$,
number of function evaluation and success rate.
Tidy
Tidy fit results for all the parameters
Step6:  The tidy function returns one row for each parameter.
Step7:  Augment
Tidy dataframe with data function of the independent variable ('x'). Columns include
the data being fitted, best fit, best fit components, residuals, etc.
Step8:  The augment function returns one row for each data point.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
from numpy import sqrt, pi, exp, linspace
from lmfit import Model
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format='retina'  # for hi-dpi displays
import lmfit
print('lmfit: %s' % lmfit.__version__)
import pybroom as br
Explanation: PyBroom Example - Simple
This notebook is part of pybroom.
This notebook shows the simplest usage of pybroom when performing
a curve fit of a single dataset. Possible applications are only hinted.
For a more complex (and interesting!) example using multiple datasets see
pybroom-example-multi-datasets.
End of explanation
x = np.linspace(-10, 10, 101)
peak1 = lmfit.models.GaussianModel(prefix='p1_')
peak2 = lmfit.models.GaussianModel(prefix='p2_')
model = peak1 + peak2
params = model.make_params(p1_amplitude=1, p2_amplitude=1, 
                           p1_sigma=1, p2_sigma=1)
y_data = model.eval(x=x, p1_center=-1, p2_center=2, p1_sigma=0.5, p2_sigma=1, p1_amplitude=1, p2_amplitude=2)
y_data.shape
y_data += np.random.randn(*y_data.shape)/10
plt.plot(x, y_data)
Explanation: Create Noisy Data
End of explanation
params = model.make_params(p1_center=0, p2_center=3, 
                           p1_sigma=0.5, p2_sigma=1, 
                           p1_amplitude=1, p2_amplitude=2)
result = model.fit(y_data, x=x, params=params)
Explanation: Model Fitting
End of explanation
print(result.fit_report())
result.params.pretty_print()
Explanation: Fit result from an lmfit Model can be inspected with
with fit_report or params.pretty_print():
End of explanation
dg = br.glance(result)
dg.drop('model', 1).drop('message', 1)
Explanation: These methods a re convenient but extracting the data
from the lmfit object requires some work and the knowledge
of lmfit object structure.
pybroom comes to help, extracting data from fit results and
returning  pandas DataFrame in tidy format that can be 
much more easily manipulated, filtered and plotted.
Glance
Glancing at the fit results (dropping some verbose columns):
End of explanation
dt = br.tidy(result)
dt
Explanation: The glance 
function returns a DataFrame with one row per fit-result object.
Application Idea
If you fit N models to the same dataset
you can compare statistics such as reduced-$\chi^2$
Or, fitting several with several methods (and datasets) you
can study the convergence properties using reduced-$\chi^2$,
number of function evaluation and success rate.
Tidy
Tidy fit results for all the parameters:
End of explanation
dt.loc[dt.name == 'p1_center']
Explanation: The tidy function returns one row for each parameter.
End of explanation
da = br.augment(result)
da.head()
Explanation: Augment
Tidy dataframe with data function of the independent variable ('x'). Columns include
the data being fitted, best fit, best fit components, residuals, etc.
End of explanation
d = br.augment(result)
fig, ax = plt.subplots(2, 1, figsize=(7, 8))
ax[1].plot('x', 'data', data=d, marker='o', ls='None')
ax[1].plot('x', "Model(gaussian, prefix='p1_')", data=d, lw=2, ls='--')
ax[1].plot('x', "Model(gaussian, prefix='p2_')", data=d, lw=2, ls='--')
ax[1].plot('x', 'best_fit', data=d, lw=2)
ax[0].plot('x', 'residual', data=d);
Explanation: The augment function returns one row for each data point.
End of explanation
<END_TASK>