Python之二维正态分布采样置信椭圆绘制

 更新时间:2023年02月01日 11:49:22   作者:犹有傲霜枝  
这篇文章主要介绍了Python之二维正态分布采样置信椭圆绘制方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

二维正态分布采样后,绘制置信椭圆

假设二维正态分布表示为:

下图为两个二维高斯分布采样后的置信椭圆

每个二维高斯分布采样100个数据点,图片为:

代码如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

def make_ellipses(mean, cov, ax, confidence=5.991, alpha=0.3, color="blue", eigv=False, arrow_color_list=None):
    """
    多元正态分布
    mean: 均值
    cov: 协方差矩阵
    ax: 画布的Axes对象
    confidence: 置信椭圆置信率 # 置信区间, 95%: 5.991  99%: 9.21  90%: 4.605 
    alpha: 椭圆透明度
    eigv: 是否画特征向量
    arrow_color_list: 箭头颜色列表
    """
    lambda_, v = np.linalg.eig(cov)    # 计算特征值lambda_和特征向量v
    # print "lambda: ", lambda_
    # print "v: ", v
    # print "v[0, 0]: ", v[0, 0]

    sqrt_lambda = np.sqrt(np.abs(lambda_))    # 存在负的特征值, 无法开方,取绝对值

    s = confidence
    width = 2 * np.sqrt(s) * sqrt_lambda[0]    # 计算椭圆的两倍长轴
    height = 2 * np.sqrt(s) * sqrt_lambda[1]   # 计算椭圆的两倍短轴
    angle = np.rad2deg(np.arccos(v[0, 0]))    # 计算椭圆的旋转角度
    ell = mpl.patches.Ellipse(xy=mean, width=width, height=height, angle=angle, color=color)    # 绘制椭圆

    ax.add_artist(ell)
    ell.set_alpha(alpha)
    # 是否画出特征向量
    if eigv:
        # print "type(v): ", type(v)
        if arrow_color_list is None:
            arrow_color_list = [color for i in range(v.shape[0])]
        for i in range(v.shape[0]):
            v_i = v[:, i]
            scale_variable = np.sqrt(s) * sqrt_lambda[i]
            # 绘制箭头
            """
            ax.arrow(x, y, dx, dy,    # (x, y)为箭头起始坐标,(dx, dy)为偏移量
                     width,    # 箭头尾部线段宽度
                     length_includes_head,    # 长度是否包含箭头
                     head_width,    # 箭头宽度
                     head_length,    # 箭头长度
                     color,    # 箭头颜色
                     )
            """
            ax.arrow(mean[0], mean[1], scale_variable*v_i[0], scale_variable * v_i[1], 
                     width=0.05, 
                     length_includes_head=True, 
                     head_width=0.2, 
                     head_length=0.3,
                     color=arrow_color_list[i])
            # ax.annotate("", 
            #             xy=(mean[0] + lambda_[i] * v_i[0], mean[1] + lambda_[i] * v_i[1]),
            #             xytext=(mean[0], mean[1]),
            #             arrowprops=dict(arrowstyle="->", color=arrow_color_list[i]))


    # v, w = np.linalg.eigh(cov)
    # print "v: ", v

    # # angle = np.rad2deg(np.arccos(w))
    # u = w[0] / np.linalg.norm(w[0])
    # angle = np.arctan2(u[1], u[0])
    # angle = 180 * angle / np.pi
    # s = 5.991   # 置信区间, 95%: 5.991  99%: 9.21  90%: 4.605 
    # v = 2.0 * np.sqrt(s) * np.sqrt(v)
    # ell = mpl.patches.Ellipse(xy=mean, width=v[0], height=v[1], angle=180 + angle, color="red")
    # ell.set_clip_box(ax.bbox)
    # ell.set_alpha(0.5)
    # ax.add_artist(ell)

def plot_2D_gaussian_sampling(mean, cov, ax, data_num=100, confidence=5.991, color="blue", alpha=0.3, eigv=False):
    """
    mean: 均值
    cov: 协方差矩阵
    ax: Axes对象
    confidence: 置信椭圆的置信率
    data_num: 散点采样数量
    color: 颜色
    alpha: 透明度
    eigv: 是否画特征向量的箭头
    """
    if isinstance(mean, list) and len(mean) > 2:
        print "多元正态分布,多于2维"
        mean = mean[:2]
        cov_temp = []
        for i in range(2):
            cov_temp.append(cov[i][:2])
        cov = cov_temp
    elif isinstance(mean, np.ndarray) and mean.shape[0] > 2:
        mean = mean[:2]
        cov = cov[:2, :2]
    data = np.random.multivariate_normal(mean, cov, 100)
    x, y = data.T
    plt.scatter(x, y, s=10, c=color)
    make_ellipses(mean, cov, ax, confidence=confidence, color=color, alpha=alpha, eigv=eigv)


def main():
    # plt.figure("Multivariable Gaussian Distribution")
    plt.rcParams["figure.figsize"] = (8.0, 8.0)
    fig, ax = plt.subplots()
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    print "ax:", ax

    mean = [4, 0]
    cov = [[1, 0.9], 
           [0.9, 0.5]]
    
    plot_2D_gaussian_sampling(mean=mean, cov=cov, ax=ax, eigv=True, color="r")

    mean1 = [5, 2]
    cov1 = [[1, 0],
           [0, 1]]
    plot_2D_gaussian_sampling(mean=mean1, cov=cov1, ax=ax, eigv=True)

    plt.savefig("./get_pickle_data/pic/gaussian_covariance_matrix.png")
    plt.show()



if __name__ == "__main__":
    main()


总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python实现

    Python实现"验证回文串"的几种方法

    这篇文章主要介绍了Python实现"验证回文串"的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • python常见运算符及用法小结

    python常见运算符及用法小结

    python中的运算符主要包括算术运算符,关系(比较)运算符,赋值运算符,逻辑运算符,成员运算符,身份运算符,三目运算符。使用运算符将不同类型的数据按照一定的规则连接起来的式子,称为表达式。下面将介绍一些常用的运算符
    2022-08-08
  • python数据结构之搜索讲解

    python数据结构之搜索讲解

    这篇文章主要介绍了python数据结构之搜索讲解,搜索是指从元素集合中找到某个特定元素的算法过程。搜索过程通常返回 True 或 False, 分别表示元素是否存在,下面一起来了解文章的详细内容吧,希望对你有所帮助
    2021-12-12
  • python+opencv轮廓检测代码解析

    python+opencv轮廓检测代码解析

    这篇文章主要介绍了python+opencv轮廓检测代码解析,本文实例实现对图片的简单处理,比如图片的读取,灰度显示等相关内容,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • python爬虫流程基础示例零基础学习

    python爬虫流程基础示例零基础学习

    这篇文章主要为大家介绍了python爬虫流程基础示例零基础学习,我们将讨论 Python 网络编程中的爬虫基础,作为一个完全的初学者,你将学习到爬虫的基本概念、常用库以及如何编写一个简单的爬虫
    2023-06-06
  • python matplotlib坐标轴设置的方法

    python matplotlib坐标轴设置的方法

    本篇文章主要介绍了python matplotlib坐标轴设置的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Python scipy实现差分进化算法

    Python scipy实现差分进化算法

    差分进化算法是广义的遗传算法的一种,核心思想是变异,这篇文章主要为大家介绍的则是著名的scipy库中对差分进化算法的实现,希望对大家有所帮助
    2023-08-08
  • 在Python的Django框架中显示对象子集的方法

    在Python的Django框架中显示对象子集的方法

    这篇文章主要介绍了在Python的Django框架中显示对象子集的方法,即queryset的参数的使用相关,需要的朋友可以参考下
    2015-07-07
  • pygame学习笔记(5):游戏精灵

    pygame学习笔记(5):游戏精灵

    这篇文章主要介绍了pygame学习笔记(5):游戏精灵,本文讲解了什么是精灵、sprite中主要且常用的变量、建立一个简单的精灵、学习精灵组、动画等内容,需要的朋友可以参考下
    2015-04-04
  • Python实现把xml或xsl转换为html格式

    Python实现把xml或xsl转换为html格式

    这篇文章主要介绍了Python实现把xml或xsl转换为html格式,本文直接给出实现代码,需要的朋友可以参考下
    2015-04-04

最新评论