Example #1
0
def draw_ellipse(pos, cov, nsig=None, ax=None, label="temp",
                 set_label=True, **kwrgs):
    """
    Plots an ellipse enclosing *volume* based on the specified covariance
    matrix (*cov*) and location (*pos*). Additional keyword arguments are
    passed on to the ellipse patch artist.

    Parameters
    ----------
        cov : The 2x2 covariance matrix to base the ellipse on
        pos : The location of the center of the ellipse. Expects a 2-element
            sequence of [x0, y0].
        volume : The volume inside the ellipse; defaults to 0.5
        ax : The axis that the ellipse will be plotted on. Defaults to the
            current axis.
    """
    def eigsorted(cov):
        vals, vecs = np.linalg.eigh(cov)
        order = vals.argsort()[::-1]
        return vals[order], vecs[:, order]

    if ax is None:
        fig, ax = plt.subplots(1)
    if nsig is None:
        nsig = [1, 2]

    vals, vecs = eigsorted(cov)
    theta = np.degrees(np.arctan2(*vecs[:, 0][::-1]))

    # Width and height are "full" widths, not radius
    for ele in nsig:
        scale = np.sqrt(chi2.ppf(erf(ele / np.sqrt(2)), df=2))
        width, height = 2 * scale * np.sqrt(vals)
        ellip = Ellipse(xy=pos, width=width, height=height, angle=theta, **kwrgs)

        ax.add_artist(ellip)
        ellip.set_clip_box(ax.bbox)

    ellip.set_label(label)

    # Limit the axes correctly to show the plots
    ax.set_xlim(pos[0] - 2 * width, pos[0] + 2 * width)
    ax.set_ylim(pos[1] - 2 * height, pos[1] + 2 * height)

    if set_label:
        ax.legend(handles=[plt.plot([], ls="-")[0]],
                  labels=[ellip.get_label()])
    return ax