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

.. only:: html

    .. meta::
        :keywords: codex

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

        :ref:`Go to the end <sphx_glr_download_gallery_statistics_confidence_ellipse.py>`
        to download the full example code.

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

.. _sphx_glr_gallery_statistics_confidence_ellipse.py:


======================================================
Plot a confidence ellipse of a two-dimensional dataset
======================================================

This example shows how to plot a confidence ellipse of a
two-dimensional dataset, using its pearson correlation coefficient.

The approach that is used to obtain the correct geometry is
explained and proved here:

https://carstenschelp.github.io/2018/09/14/Plot_Confidence_Ellipse_001.html

The method avoids the use of an iterative eigen decomposition algorithm
and makes use of the fact that a normalized covariance matrix (composed of
pearson correlation coefficients and ones) is particularly easy to handle.

.. GENERATED FROM PYTHON SOURCE LINES 18-26

.. code-block:: Python



    import matplotlib.pyplot as plt
    import numpy as np

    from matplotlib.patches import Ellipse
    import matplotlib.transforms as transforms








.. GENERATED FROM PYTHON SOURCE LINES 27-39

The plotting function itself
""""""""""""""""""""""""""""

This function plots the confidence ellipse of the covariance of the given
array-like variables x and y. The ellipse is plotted into the given
Axes object *ax*.

The radiuses of the ellipse can be controlled by n_std which is the number
of standard deviations. The default value is 3 which makes the ellipse
enclose 98.9% of the points if the data is normally distributed
like in these examples (3 standard deviations in 1-D contain 99.7%
of the data, which is 98.9% of the data in 2-D).

.. GENERATED FROM PYTHON SOURCE LINES 40-95

.. code-block:: Python



    def confidence_ellipse(x, y, ax, n_std=3.0, facecolor='none', **kwargs):
        """
        Create a plot of the covariance confidence ellipse of *x* and *y*.

        Parameters
        ----------
        x, y : array-like, shape (n, )
            Input data.

        ax : matplotlib.axes.Axes
            The Axes object to draw the ellipse into.

        n_std : float
            The number of standard deviations to determine the ellipse's radiuses.

        **kwargs
            Forwarded to `~matplotlib.patches.Ellipse`

        Returns
        -------
        matplotlib.patches.Ellipse
        """
        if x.size != y.size:
            raise ValueError("x and y must be the same size")

        cov = np.cov(x, y)
        pearson = cov[0, 1]/np.sqrt(cov[0, 0] * cov[1, 1])
        # Using a special case to obtain the eigenvalues of this
        # two-dimensional dataset.
        ell_radius_x = np.sqrt(1 + pearson)
        ell_radius_y = np.sqrt(1 - pearson)
        ellipse = Ellipse((0, 0), width=ell_radius_x * 2, height=ell_radius_y * 2,
                          facecolor=facecolor, **kwargs)

        # Calculating the standard deviation of x from
        # the squareroot of the variance and multiplying
        # with the given number of standard deviations.
        scale_x = np.sqrt(cov[0, 0]) * n_std
        mean_x = np.mean(x)

        # calculating the standard deviation of y ...
        scale_y = np.sqrt(cov[1, 1]) * n_std
        mean_y = np.mean(y)

        transf = transforms.Affine2D() \
            .rotate_deg(45) \
            .scale(scale_x, scale_y) \
            .translate(mean_x, mean_y)

        ellipse.set_transform(transf + ax.transData)
        return ax.add_patch(ellipse)









.. GENERATED FROM PYTHON SOURCE LINES 96-103

A helper function to create a correlated dataset
""""""""""""""""""""""""""""""""""""""""""""""""

Creates a random two-dimensional dataset with the specified
two-dimensional mean (mu) and dimensions (scale).
The correlation can be controlled by the param 'dependency',
a 2x2 matrix.

.. GENERATED FROM PYTHON SOURCE LINES 104-114

.. code-block:: Python


    def get_correlated_dataset(n, dependency, mu, scale):
        latent = np.random.randn(n, 2)
        dependent = latent.dot(dependency)
        scaled = dependent * scale
        scaled_with_offset = scaled + mu
        # return x and y of the new, correlated dataset
        return scaled_with_offset[:, 0], scaled_with_offset[:, 1]









.. GENERATED FROM PYTHON SOURCE LINES 115-123

Positive, negative and weak correlation
"""""""""""""""""""""""""""""""""""""""

Note that the shape for the weak correlation (right) is an ellipse,
not a circle because x and y are differently scaled.
However, the fact that x and y are uncorrelated is shown by
the axes of the ellipse being aligned with the x- and y-axis
of the coordinate system.

.. GENERATED FROM PYTHON SOURCE LINES 124-155

.. code-block:: Python


    np.random.seed(0)

    PARAMETERS = {
        'Positive correlation': [[0.85, 0.35],
                                 [0.15, -0.65]],
        'Negative correlation': [[0.9, -0.4],
                                 [0.1, -0.6]],
        'Weak correlation': [[1, 0],
                             [0, 1]],
    }

    mu = 2, 4
    scale = 3, 5

    fig, axs = plt.subplots(1, 3, figsize=(9, 3))
    for ax, (title, dependency) in zip(axs, PARAMETERS.items()):
        x, y = get_correlated_dataset(800, dependency, mu, scale)
        ax.scatter(x, y, s=0.5)

        ax.axvline(c='grey', lw=1)
        ax.axhline(c='grey', lw=1)

        confidence_ellipse(x, y, ax, edgecolor='red')

        ax.scatter(mu[0], mu[1], c='red', s=3)
        ax.set_title(title)

    plt.show()





.. image-sg:: /gallery/statistics/images/sphx_glr_confidence_ellipse_001.png
   :alt: Positive correlation, Negative correlation, Weak correlation
   :srcset: /gallery/statistics/images/sphx_glr_confidence_ellipse_001.png, /gallery/statistics/images/sphx_glr_confidence_ellipse_001_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 156-160

Different number of standard deviations
"""""""""""""""""""""""""""""""""""""""

A plot with n_std = 3 (blue), 2 (purple) and 1 (red)

.. GENERATED FROM PYTHON SOURCE LINES 161-188

.. code-block:: Python


    fig, ax_nstd = plt.subplots(figsize=(6, 6))

    dependency_nstd = [[0.8, 0.75],
                       [-0.2, 0.35]]
    mu = 0, 0
    scale = 8, 5

    ax_nstd.axvline(c='grey', lw=1)
    ax_nstd.axhline(c='grey', lw=1)

    x, y = get_correlated_dataset(500, dependency_nstd, mu, scale)
    ax_nstd.scatter(x, y, s=0.5)

    confidence_ellipse(x, y, ax_nstd, n_std=1,
                       label=r'$1\sigma$', edgecolor='firebrick')
    confidence_ellipse(x, y, ax_nstd, n_std=2,
                       label=r'$2\sigma$', edgecolor='fuchsia', linestyle='--')
    confidence_ellipse(x, y, ax_nstd, n_std=3,
                       label=r'$3\sigma$', edgecolor='blue', linestyle=':')

    ax_nstd.scatter(mu[0], mu[1], c='red', s=3)
    ax_nstd.set_title('Different standard deviations')
    ax_nstd.legend()
    plt.show()





.. image-sg:: /gallery/statistics/images/sphx_glr_confidence_ellipse_002.png
   :alt: Different standard deviations
   :srcset: /gallery/statistics/images/sphx_glr_confidence_ellipse_002.png, /gallery/statistics/images/sphx_glr_confidence_ellipse_002_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 189-194

Using the keyword arguments
"""""""""""""""""""""""""""

Use the keyword arguments specified for `matplotlib.patches.Patch` in order
to have the ellipse rendered in different ways.

.. GENERATED FROM PYTHON SOURCE LINES 195-218

.. code-block:: Python


    fig, ax_kwargs = plt.subplots(figsize=(6, 6))
    dependency_kwargs = [[-0.8, 0.5],
                         [-0.2, 0.5]]
    mu = 2, -3
    scale = 6, 5

    ax_kwargs.axvline(c='grey', lw=1)
    ax_kwargs.axhline(c='grey', lw=1)

    x, y = get_correlated_dataset(500, dependency_kwargs, mu, scale)
    # Plot the ellipse with zorder=0 in order to demonstrate
    # its transparency (caused by the use of alpha).
    confidence_ellipse(x, y, ax_kwargs,
                       alpha=0.5, facecolor='pink', edgecolor='purple', zorder=0)

    ax_kwargs.scatter(x, y, s=0.5)
    ax_kwargs.scatter(mu[0], mu[1], c='red', s=3)
    ax_kwargs.set_title('Using keyword arguments')

    fig.subplots_adjust(hspace=0.25)
    plt.show()




.. image-sg:: /gallery/statistics/images/sphx_glr_confidence_ellipse_003.png
   :alt: Using keyword arguments
   :srcset: /gallery/statistics/images/sphx_glr_confidence_ellipse_003.png, /gallery/statistics/images/sphx_glr_confidence_ellipse_003_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 219-234

.. tags::

   plot-type: speciality
   plot-type: scatter
   component: ellipse
   component: patch
   domain: statistics

.. admonition:: References

   The use of the following functions, methods, classes and modules is shown
   in this example:

   - `matplotlib.transforms.Affine2D`
   - `matplotlib.patches.Ellipse`


.. _sphx_glr_download_gallery_statistics_confidence_ellipse.py:

.. only:: html

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

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

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

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

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

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

      :download:`Download zipped: confidence_ellipse.zip <confidence_ellipse.zip>`


.. only:: html

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

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