.. 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 .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` 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:: default import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Ellipse import matplotlib.transforms as transforms .. GENERATED FROM PYTHON SOURCE LINES 27-38 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 99.7% of the points (given the data is normally distributed like in these examples). .. GENERATED FROM PYTHON SOURCE LINES 39-94 .. code-block:: default 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-dimensionl 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 stdandard 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 stdandard 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 95-102 A helper function to create a correlated dataset """""""""""""""""""""""""""""""""""""""""""""""" Creates a random two-dimesional 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 103-113 .. code-block:: default 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 114-122 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 123-154 .. code-block:: default 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:: /gallery/statistics/images/sphx_glr_confidence_ellipse_001.png :alt: Positive correlation, Negative correlation, Weak correlation :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 155-159 Different number of standard deviations """"""""""""""""""""""""""""""""""""""" A plot with n_std = 3 (blue), 2 (purple) and 1 (red) .. GENERATED FROM PYTHON SOURCE LINES 160-187 .. code-block:: default 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:: /gallery/statistics/images/sphx_glr_confidence_ellipse_002.png :alt: Different standard deviations :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 188-193 Using the keyword arguments """"""""""""""""""""""""""" Use the kwargs specified for matplotlib.patches.Patch in order to have the ellipse rendered in different ways. .. GENERATED FROM PYTHON SOURCE LINES 194-216 .. code-block:: default 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 kwargs') fig.subplots_adjust(hspace=0.25) plt.show() .. image:: /gallery/statistics/images/sphx_glr_confidence_ellipse_003.png :alt: Using kwargs :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 1.337 seconds) .. _sphx_glr_download_gallery_statistics_confidence_ellipse.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: confidence_ellipse.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: confidence_ellipse.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature Keywords: matplotlib code example, codex, python plot, pyplot `Gallery generated by Sphinx-Gallery `_