
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/example_fit_multi_datasets_Model-interface.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_example_fit_multi_datasets_Model-interface.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_example_fit_multi_datasets_Model-interface.py:


Fit Multiple Data Sets Using Model Interface
============================================

Fitting multiple (simulated) Gaussian data sets simultaneously, using the
Model interface.

All minimizers require the residual array to be one-dimensional. Therefore,
in the ``objective`` function we need to ``flatten`` the array before
returning it.

.. GENERATED FROM PYTHON SOURCE LINES 13-19

.. code-block:: Python

    import matplotlib.pyplot as plt
    import numpy as np

    from lmfit import Parameters, minimize, report_fit
    from lmfit.models import GaussianModel








.. GENERATED FROM PYTHON SOURCE LINES 20-21

Create N simulated Gaussian data sets

.. GENERATED FROM PYTHON SOURCE LINES 21-36

.. code-block:: Python

    N = 5
    np.random.seed(2021)
    x = np.linspace(-1, 2, 151)
    data = []
    for _ in np.arange(N):
        params = Parameters()
        params.add('amplitude', value=0.60 + 9.50*np.random.rand())
        params.add('center', value=-0.20 + 1.20*np.random.rand())
        params.add('sigma', value=0.25 + 0.03*np.random.rand())
        dat = (GaussianModel().eval(x=x, params=params) +
               np.random.normal(size=x.size, scale=0.1))
        data.append(dat)
    data = np.array(data)









.. GENERATED FROM PYTHON SOURCE LINES 37-39

The objective function will extract and evaluate a Gaussian from the
compound model

.. GENERATED FROM PYTHON SOURCE LINES 39-53

.. code-block:: Python

    def objective(params, x, data, model):
        """Calculate total residual for fits of Gaussians to several data sets."""
        ndata, _ = data.shape
        resid = 0.0*data[:]

        # make residual per data set
        for i in range(ndata):
            components = model.components[i].eval(params=params, x=x)
            resid[i, :] = data[i, :] - components

        # now flatten this to a 1D array, as minimize() needs
        return resid.flatten()









.. GENERATED FROM PYTHON SOURCE LINES 54-55

Create a composite model by adding Gaussians

.. GENERATED FROM PYTHON SOURCE LINES 55-58

.. code-block:: Python

    model_arr = [GaussianModel(prefix=f'n{i+1}_') for i, _ in enumerate(data)]
    model = sum(model_arr[1:], start=model_arr[0])








.. GENERATED FROM PYTHON SOURCE LINES 59-61

Prepare the fitting parameters and constrain n2_sigma, ..., nN_sigma to be
equal to n1_sigma

.. GENERATED FROM PYTHON SOURCE LINES 61-70

.. code-block:: Python

    fit_params = model.make_params()
    for iy, y in enumerate(data):
        fit_params.add(f'n{iy+1}_amplitude', value=0.5, min=0.0, max=200)
        fit_params.add(f'n{iy+1}_center', value=0.4, min=-2.0, max=2.0)
        fit_params.add(f'n{iy+1}_sigma', value=0.3, min=0.01, max=3.0)

        if iy > 0:
            fit_params[f'n{iy+1}_sigma'].expr = 'n1_sigma'








.. GENERATED FROM PYTHON SOURCE LINES 71-72

Run the global fit and show the fitting result

.. GENERATED FROM PYTHON SOURCE LINES 72-75

.. code-block:: Python

    out = minimize(objective, fit_params, args=(x, data, model))
    report_fit(out.params)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    [[Variables]]
        n1_amplitude:  6.40552155 +/- 0.01575090 (0.25%) (init = 0.5)
        n1_center:     0.68032886 +/- 8.6209e-04 (0.13%) (init = 0.4)
        n1_sigma:      0.25743367 +/- 3.4131e-04 (0.13%) (init = 0.3)
        n2_amplitude:  6.98975626 +/- 0.01585971 (0.23%) (init = 0.5)
        n2_center:     0.50446887 +/- 7.9004e-04 (0.16%) (init = 0.4)
        n2_sigma:      0.25743367 +/- 3.4131e-04 (0.13%) == 'n1_sigma'
        n3_amplitude:  7.30195609 +/- 0.01592142 (0.22%) (init = 0.5)
        n3_center:    -0.08261146 +/- 7.5626e-04 (0.92%) (init = 0.4)
        n3_sigma:      0.25743367 +/- 3.4131e-04 (0.13%) == 'n1_sigma'
        n4_amplitude:  6.01461340 +/- 0.01568302 (0.26%) (init = 0.5)
        n4_center:     0.07382999 +/- 9.1812e-04 (1.24%) (init = 0.4)
        n4_sigma:      0.25743367 +/- 3.4131e-04 (0.13%) == 'n1_sigma'
        n5_amplitude:  9.07744386 +/- 0.01631785 (0.18%) (init = 0.5)
        n5_center:     0.34402084 +/- 6.0834e-04 (0.18%) (init = 0.4)
        n5_sigma:      0.25743367 +/- 3.4131e-04 (0.13%) == 'n1_sigma'
        n1_fwhm:       0.60620995 +/- 8.0373e-04 (0.13%) == '2.3548200*n1_sigma'
        n1_height:     9.92657076 +/- 0.02440907 (0.25%) == '0.3989423*n1_amplitude/max(1e-15, n1_sigma)'
        n2_fwhm:       0.60620995 +/- 8.0373e-04 (0.13%) == '2.3548200*n2_sigma'
        n2_height:     10.8319533 +/- 0.02457770 (0.23%) == '0.3989423*n2_amplitude/max(1e-15, n2_sigma)'
        n3_fwhm:       0.60620995 +/- 8.0373e-04 (0.13%) == '2.3548200*n3_sigma'
        n3_height:     11.3157661 +/- 0.02467331 (0.22%) == '0.3989423*n3_amplitude/max(1e-15, n3_sigma)'
        n4_fwhm:       0.60620995 +/- 8.0373e-04 (0.13%) == '2.3548200*n4_sigma'
        n4_height:     9.32078443 +/- 0.02430386 (0.26%) == '0.3989423*n4_amplitude/max(1e-15, n4_sigma)'
        n5_fwhm:       0.60620995 +/- 8.0373e-04 (0.13%) == '2.3548200*n5_sigma'
        n5_height:     14.0672212 +/- 0.02528769 (0.18%) == '0.3989423*n5_amplitude/max(1e-15, n5_sigma)'
    [[Correlations]] (unreported correlations are < 0.100)
        C(n1_sigma, n5_amplitude)     = +0.3688
        C(n1_sigma, n3_amplitude)     = +0.3040
        C(n1_sigma, n2_amplitude)     = +0.2922
        C(n1_amplitude, n1_sigma)     = +0.2696
        C(n1_sigma, n4_amplitude)     = +0.2542
        C(n3_amplitude, n5_amplitude) = +0.1121
        C(n2_amplitude, n5_amplitude) = +0.1077




.. GENERATED FROM PYTHON SOURCE LINES 76-77

Plot the data sets and fits

.. GENERATED FROM PYTHON SOURCE LINES 77-83

.. code-block:: Python

    plt.figure()
    for i, y in enumerate(data):
        components = model.eval_components(params=out.params, x=x)
        plt.plot(x, y, 'o', x, components[f'n{i+1}_'], '-')

    plt.show()



.. image-sg:: /examples/images/sphx_glr_example_fit_multi_datasets_Model-interface_001.png
   :alt: example fit multi datasets Model interface
   :srcset: /examples/images/sphx_glr_example_fit_multi_datasets_Model-interface_001.png, /examples/images/sphx_glr_example_fit_multi_datasets_Model-interface_001_3_00x.png 3.00x
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.360 seconds)


.. _sphx_glr_download_examples_example_fit_multi_datasets_Model-interface.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: example_fit_multi_datasets_Model-interface.ipynb <example_fit_multi_datasets_Model-interface.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: example_fit_multi_datasets_Model-interface.py <example_fit_multi_datasets_Model-interface.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: example_fit_multi_datasets_Model-interface.zip <example_fit_multi_datasets_Model-interface.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
