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

作者:犹有傲霜枝 时间:2021-04-08 06:39:09 

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

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

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

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

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

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

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

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

代码如下

#!/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()

来源:https://blog.csdn.net/qq_41009742/article/details/114871413

标签:二维正态分布采样,置信椭圆,Python
0
投稿

猜你喜欢

  • pytorch多GPU并行运算的实现

    2022-01-09 22:01:06
  • python 基于selenium实现鼠标拖拽功能

    2022-10-30 17:03:07
  • 简单了解python列表和元组的区别

    2022-02-11 17:14:43
  • Oracle DBA常用语句

    2009-08-05 20:15:00
  • Z-Blog垃圾留言判定新方法

    2009-07-06 13:04:00
  • jquery的$(document).ready()和onload的加载顺序

    2023-08-23 18:57:40
  • python读取dicom图像示例(SimpleITK和dicom包实现)

    2023-07-06 14:08:10
  • 音视频基本概念和FFmpeg的简单入门教程详解

    2023-03-24 22:27:23
  • img标签中alt和title属性的正确使用

    2008-01-10 12:59:00
  • Pyecharts可视化图片渲染的方法详解

    2021-02-02 22:39:30
  • Python实现获取照片拍摄日期并重命名的方法

    2023-04-14 03:26:37
  • 详解CSS3中的属性选择符

    2008-04-24 14:30:00
  • python版本的仿windows计划任务工具

    2021-06-09 03:55:07
  • Python decimal模块的使用示例详解

    2023-02-13 15:49:52
  • Python函数必须先定义,后调用说明(函数调用函数例外)

    2022-03-06 18:03:53
  • python获取糗百图片代码实例

    2022-09-10 01:44:01
  • Python中的进程操作模块(multiprocess.process)

    2022-09-17 23:10:32
  • PHP attributes()函数讲解

    2023-06-04 09:33:02
  • laravel入门知识点整理

    2023-05-31 13:42:33
  • Python中的pandas库简介及其使用教程

    2022-02-10 17:11:12
  • asp之家 网络编程 m.aspxhome.com