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

    Click :ref:`here <sphx_glr_download_examples_example_confidence_interval.py>` to download the full example code
.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_example_confidence_interval.py:


Calculate Confidence Intervals
==============================


.. code-block:: default

    import matplotlib.pyplot as plt
    from numpy import argsort, exp, linspace, pi, random, sign, sin, unique
    from scipy.interpolate import interp1d

    from lmfit import (Minimizer, Parameters, conf_interval, conf_interval2d,
                       report_ci, report_fit)







Define the residual function, specify "true" parameter values, and generate
a synthetic data set with some noise:


.. code-block:: default



    def residual(pars, x, data=None):
        argu = (x*pars['decay'])**2
        shift = pars['shift']
        if abs(shift) > pi/2:
            shift = shift - sign(shift)*pi
        model = pars['amp']*sin(shift + x/pars['period']) * exp(-argu)
        if data is None:
            return model
        return model - data


    p_true = Parameters()
    p_true.add('amp', value=14.0)
    p_true.add('period', value=5.33)
    p_true.add('shift', value=0.123)
    p_true.add('decay', value=0.010)

    x = linspace(0.0, 250.0, 2500)
    noise = random.normal(scale=0.7215, size=x.size)
    data = residual(p_true, x) + noise







Create fitting parameters and set initial values:


.. code-block:: default

    fit_params = Parameters()
    fit_params.add('amp', value=13.0)
    fit_params.add('period', value=2)
    fit_params.add('shift', value=0.0)
    fit_params.add('decay', value=0.02)







Set-up the minimizer and perform the fit using leastsq algorithm, and show
the report:


.. code-block:: default

    mini = Minimizer(residual, fit_params, fcn_args=(x,), fcn_kws={'data': data})
    out = mini.leastsq()

    fit = residual(out.params, x)
    report_fit(out)





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

 Out:

 .. code-block:: none

    [[Fit Statistics]]
        # fitting method   = leastsq
        # function evals   = 90
        # data points      = 2500
        # variables        = 4
        chi-square         = 1212.08286
        reduced chi-square = 0.48561012
        Akaike info crit   = -1801.87620
        Bayesian info crit = -1778.58002
    [[Variables]]
        amp:     13.9952862 +/- 0.04810194 (0.34%) (init = 13)
        period:  5.32947061 +/- 0.00267669 (0.05%) (init = 2)
        shift:   0.12201493 +/- 0.00472513 (3.87%) (init = 0)
        decay:   0.01002913 +/- 3.9913e-05 (0.40%) (init = 0.02)
    [[Correlations]] (unreported correlations are < 0.100)
        C(period, shift) =  0.800
        C(amp, decay)    =  0.576



Calculate the confidence intervals for parameters and display the results:


.. code-block:: default

    ci, tr = conf_interval(mini, out, trace=True)

    report_ci(ci)

    names = out.params.keys()
    i = 0
    gs = plt.GridSpec(4, 4)
    sx = {}
    sy = {}
    for fixed in names:
        j = 0
        for free in names:
            if j in sx and i in sy:
                ax = plt.subplot(gs[i, j], sharex=sx[j], sharey=sy[i])
            elif i in sy:
                ax = plt.subplot(gs[i, j], sharey=sy[i])
                sx[j] = ax
            elif j in sx:
                ax = plt.subplot(gs[i, j], sharex=sx[j])
                sy[i] = ax
            else:
                ax = plt.subplot(gs[i, j])
                sy[i] = ax
                sx[j] = ax
            if i < 3:
                plt.setp(ax.get_xticklabels(), visible=False)
            else:
                ax.set_xlabel(free)

            if j > 0:
                plt.setp(ax.get_yticklabels(), visible=False)
            else:
                ax.set_ylabel(fixed)

            res = tr[fixed]
            prob = res['prob']
            f = prob < 0.96

            x, y = res[free], res[fixed]
            ax.scatter(x[f], y[f], c=1-prob[f], s=200*(1-prob[f]+0.5))
            ax.autoscale(1, 1)
            j += 1
        i += 1





.. image:: /examples/images/sphx_glr_example_confidence_interval_001.png
    :class: sphx-glr-single-img


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

 Out:

 .. code-block:: none

               99.73%    95.45%    68.27%    _BEST_    68.27%    95.45%    99.73%
     amp   :  -0.14396  -0.09606  -0.04806  13.99529  +0.04794  +0.09637  +0.14466
     period:  -0.00807  -0.00532  -0.00267   5.32947  +0.00267  +0.00534  +0.00811
     shift :  -0.01420  -0.00947  -0.00473   0.12201  +0.00474  +0.00948  +0.01423
     decay :  -0.00012  -0.00008  -0.00004   0.01003  +0.00004  +0.00008  +0.00012



It is also possible to calculate the confidence regions for two fixed
parameters using the function ``conf_interval2d``:


.. code-block:: default

    names = list(out.params.keys())

    plt.figure()
    cm = plt.cm.coolwarm
    for i in range(4):
        for j in range(4):
            plt.subplot(4, 4, 16-j*4-i)
            if i != j:
                x, y, m = conf_interval2d(mini, out, names[i], names[j], 20, 20)
                plt.contourf(x, y, m, linspace(0, 1, 10), cmap=cm)
                plt.xlabel(names[i])
                plt.ylabel(names[j])

                x = tr[names[i]][names[i]]
                y = tr[names[i]][names[j]]
                pr = tr[names[i]]['prob']
                s = argsort(x)
                plt.scatter(x[s], y[s], c=pr[s], s=30, lw=1, cmap=cm)
            else:
                x = tr[names[i]][names[i]]
                y = tr[names[i]]['prob']

                t, s = unique(x, True)
                f = interp1d(t, y[s], 'slinear')
                xn = linspace(x.min(), x.max(), 50)
                plt.plot(xn, f(xn), 'g', lw=1)
                plt.xlabel(names[i])
                plt.ylabel('prob')

    plt.show()



.. image:: /examples/images/sphx_glr_example_confidence_interval_002.png
    :class: sphx-glr-single-img


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

 Out:

 .. code-block:: none

    /Users/Newville/Codes/lmfit-py/examples/example_confidence_interval.py:135: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
      plt.show()




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

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


.. _sphx_glr_download_examples_example_confidence_interval.py:


.. only :: html

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



  .. container:: sphx-glr-download

     :download:`Download Python source code: example_confidence_interval.py <example_confidence_interval.py>`



  .. container:: sphx-glr-download

     :download:`Download Jupyter notebook: example_confidence_interval.ipynb <example_confidence_interval.ipynb>`


.. only:: html

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

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