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()

总结

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

(0)

相关推荐

  • 使用Python实现正态分布、正态分布采样

    多元正态分布(多元高斯分布) 直接从多元正态分布讲起.多元正态分布公式如下: 这就是多元正态分布的定义,均值好理解,就是高斯分布的概率分布值最大的位置,进行采样时也就是采样的中心点.而协方差矩阵在多维上形式较多. 协方差矩阵 一般来说,协方差矩阵有三种形式,分别称为球形.对角和全协方差.以二元为例: 为了方便展示不同协方差矩阵的效果,我们以二维为例.(书上截的图,凑活着看吧,是在不想画图了) 其实从这个图上可以很好的看出,协方差矩阵对正态分布的影响,也就很好明白了这三个协方差矩阵是哪里来的名字了

  • 在python中画正态分布图像的实例

    1.正态分布简介 正态分布(normal distribtution)又叫做高斯分布(Gaussian distribution),是一个非常重要也非常常见的连续概率分布.正态分布大家也都非常熟悉,下面做一些简单的介绍. 假设随机变量XX服从一个位置参数为μμ.尺度参数为σσ的正态分布,则可以记为: 而概率密度函数为 2.在python中画正态分布直方图 先直接上代码 import numpy as np import matplotlib.mlab as mlab import matplot

  • Python基于随机采样一至性实现拟合椭圆(优化版)

    上次版本如果在没有找到轮廓或轮廓的点集数很小无法拟合椭圆或在RANSAC中寻找最优解时会死循环中,优化后的代码 import cv2 import os import numpy as np import matplotlib.pyplot as plt import math from Ransac_Process import RANSAC def cul_area(x_mask, y_mask, r_circle, mask): mask_label = mask.copy() num_a

  • 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(me

  • Python实现二维曲线拟合的方法

    如下所示: from numpy import * import numpy as np import matplotlib.pyplot as plt plt.close() fig=plt.figure() plt.grid(True) plt.axis([0,10,0,8]) #列出数据 point=[[1,2],[2,3],[3,6],[4,7],[6,5],[7,3],[8,2]] plt.xlabel("X") plt.ylabel("Y") #用于求出

  • Python创建二维数组实例(关于list的一个小坑)

    0.目录 1.遇到的问题 2.创建二维数组的办法 •3.1 直接创建法 •3.2 列表生成式法 •3.3 使用模块numpy创建 1.遇到的问题 今天写Python代码的时候遇到了一个大坑,差点就耽误我交作业了... 问题是这样的,我需要创建一个二维数组,如下: m = n = 3 test = [[0] * m] * n print("test =", test) 输出结果如下: test = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 是不是看起来没有一点问

  • Python实现二维有序数组查找的方法

    本文实例讲述了Python实现二维有序数组查找的方法.分享给大家供大家参考,具体如下: 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 这题目属于比较简单但又很不容易想到的,问了两个同学,大家一时都没有想出来怎么解决比较快.第一反应都是二分查找.对于每一行进行二分查找,然后查找过程可以把某些列排除掉,这是大家都能想到的基本的思路. 比较好的另一种思路是,首先选取数组右上角

  • Python实现二维数组按照某行或列排序的方法【numpy lexsort】

    本文实例讲述了Python实现二维数组按照某行或列排序的方法.分享给大家供大家参考,具体如下: lexsort支持对数组按指定行或列的顺序排序:是间接排序,lexsort不修改原数组,返回索引. (对应lexsort 一维数组的是argsort a.argsort()这么使用就可以:argsort也不修改原数组, 返回索引) 默认按最后一行元素有小到大排序, 返回最后一行元素排序后索引所在位置. 设数组a, 返回的索引ind,ind返回的是一维数组 对于一维数组, a[ind]就是排序后的数组.

  • Python的“二维”字典 (two-dimension dictionary)定义与实现方法

    本文实例讲述了Python的"二维"字典 (two-dimension dictionary)定义与实现方法.分享给大家供大家参考,具体如下: Python 中的dict可以实现迅速查找.那么有没有像数组有二维数组一样,有二维的字典呢?比如我需要对两个关键词进行查找的时候.2D dict 可以通过 dict_2d = {'a': {'a': 1, 'b': 3}, 'b': {'a': 6}} 来建立,并通过 dict_2d['a']['b'] 来访问.但是添加一个新的 "k

  • python生成二维码的实例详解

    python生成二维码的实例详解 版本相关 操作系统:Mac OS X EI Caption Python版本:2.7 IDE:Sublime Text 3 依赖库 Python生成二维码需要的依赖库为PIL和QRcode. 坑爹的是,百度了好久都没有找到PIL,不知道是什么时候改名了,还是其他原因,pillow就是传说中的PIL. 安装命令:sudo pip install pillow.sudo pip install qrcode 验证是否安装成功,使用命令from PIL import

  • Python获取二维矩阵每列最大值的方法

    因为做项目中间有一个很小的环节需要这个功能,所以就写了一个简单的小函数,下面是具体实现: #!usr/bin/env python #encoding:utf-8 ''' __Author__:沂水寒城 ''' def get_max_value(martix): ''' 得到矩阵中每一列最大的值 ''' res_list=[] for j in range(len(martix[0])): one_list=[] for i in range(len(martix)): one_list.ap

  • Python输入二维数组方法

    前不久对于Python输入二维数组有些不解,今日成功尝试,记以备忘.这里以输入1-9,3*3矩阵为例 n=int(input()) line=[[0]*n]*n for i in range(n): line[i]=input().split(' ') print(line) 使用数据转换为int即可! 以上这篇Python输入二维数组方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 一些Python中的二维数组的操作方法 python中字

  • Python实现二维数组输出为图片

    对于二维数组,img_mask [[ 0 0 0 ..., 7 7 7] [ 0 0 0 ..., 7 7 7] [ 0 0 0 ..., 7 7 7] ..., [266 266 266 ..., 253 253 253] [266 266 266 ..., 253 253 253] [266 266 266 ..., 253 253 253]] 显示为图片的代码为: import matplotlib.pyplot as pyplot pyplot.imshow(im_mask) 以上这篇P

随机推荐