matplotlib seaborn 数据可视化(2)——2维数据平面直方图(伪等高图)

随机数据

二维正态分布
y = 1 2 π det ⁡ ( Σ ) exp ⁡ { ( x − μ ) ⊤ Σ − 1 ( x − μ ) } \mathbf{y} = \frac{1}{\sqrt{2\pi \det\left(\Sigma\right)}} \exp \left\{\left(\mathbf{x}-\mathbf{\mu}\right)^\top \Sigma^{-1} \left(\mathbf{x}-\mathbf{\mu}\right)\right\} y=2πdet(Σ) 1exp{(xμ)Σ1(xμ)}
cov = Σ = [ 1 0.8 0.8 1 ] , mu = μ = [ − 1 1 ] \text{cov}=\Sigma=\begin{bmatrix} 1&0.8\\0.8&1\end{bmatrix}, \text{mu}=\mathbf{\mu}=\begin{bmatrix}-1&1\end{bmatrix} cov=Σ=[10.80.81],mu=μ=[11]

import numpy as np
import math
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from matplotlib.image import NonUniformImage
%matplotlib

#对随机数据
mu = np.array([-1,1])
cov = np.array([[1, 0.9],[0.9, 1]])
points = 2000
data = np.random.multivariate_normal(mu,cov,int(points**2))
#data是服从2元正态分布的随机数矩阵,不能使用描点法或直接做等高线
#概率分布的形态本质上是足够多随机数做直方图所呈现的包络
#该分布中心为(-1,1),两分量方差为1
#绝大多数数据点分布在正负“3σ”内,即(-4,4)
#cov(x1,x2)=0.8表示在平面伪等高图中图形呈现“由左下到右上”拉伸
#data.shape为(2000,2)
#法1:numpy.histogram2d + matplotlib.pyplot.imshow
#法2:pandas.DataFrame + seaborn.histplot
#法3:matplotlib.hist2d 或 matplotlib.hexbin

#法1
# #指定绘图粒度
step = 0.1
#指定绘图范围
x = np.arange(mu[0]-3*cov.max(),mu[0]+3*cov.max(),step)
y = np.arange(mu[1]-3*cov.max(),mu[1]+3*cov.max(),step)
#指定统计区间
bins=(x,y)
#histogram2d
hist, xx, yy = np.histogram2d(data[:,0],data[:,1],bins=bins)
"""
interpolation : str, default: :rc:`image.interpolation`
        The interpolation method used.
    
        Supported values are 'none', 'antialiased', 'nearest', 'bilinear',
        'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite',
        'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell',
        'sinc', 'lanczos'.
origin : {'upper', 'lower'}, default: :rc:`image.origin`
        Place the [0, 0] index of the array in the upper left or lower
        left corner of the axes. The convention (the default) 'upper' is
        typically used for matrices and images.
    
        Note that the vertical axes points upward for 'lower'
        but downward for 'upper'.
"""
fig = plt.figure(1,figsize=(16,16))
ax = fig.add_subplot(221,title='random: numpy.histogram2d & matplotlib.imshow')
ax.imshow(hist, interpolation='hermite', origin='lower',cmap='YlGnBu',extent=[xx[0],xx[-1],yy[0],yy[-1]])

#法2
ax = fig.add_subplot(222,title='random: seaborn.histplot & pandas.DataFrame',aspect='equal')
sns.histplot(pd.DataFrame({"x":data[:,0],"y":data[:,1]})
             , x="x", y="y",cmap='YlGnBu')
#法3:hist2d            
ax = fig.add_subplot(223,title='random: matplotlib.hist2d',aspect='equal')
ax.hist2d(data[:,0],data[:,1],bins=bins,cmap='YlGnBu')
#法3:hexbin
ax = fig.add_subplot(224,title='random: matplotlib.hexbin',aspect='equal')
ax.hexbin(data[:,0],data[:,1],gridsize=(len(x),len(y)),cmap='YlGnBu')
plt.show()

运行结果:
在这里插入图片描述

解析数据

y = [ x 1 − μ 1 x 2 − μ 2 ] ⊤ [ c o v ( x 1 , x 1 ) c o v ( x 1 , x 2 ) c o v ( x 2 , x 1 ) c o v ( x 1 , x 2 ) ] − 1 [ x 1 − μ 1 x 2 − μ 2 ] \mathbf{y} = \begin{bmatrix} x_1-\mu_1\\x_2-\mu_2\end{bmatrix}^\top\begin{bmatrix} cov(x_1,x_1)&cov(x_1,x_2)\\cov(x_2,x_1)&cov(x_1,x_2)\end{bmatrix}^{-1}\begin{bmatrix} x_1-\mu_1\\x_2-\mu_2\end{bmatrix} y=[x1μ1x2μ2][cov(x1,x1)cov(x2,x1)cov(x1,x2)cov(x1,x2)]1[x1μ1x2μ2]

#对解析数据
#创建绘图作业面
X, Y = np.meshgrid(x, y)
#根据解析表达式得到数据
cov_inverse = np.linalg.inv(cov)
X, Y = np.meshgrid(x,y)
Z = 1/np.sqrt(2*math.pi*np.linalg.det(cov)) * np.exp(-1/2*(
    (X-mu[0])**2*cov_inverse[0,0]
    +(Y-mu[1])**2*cov_inverse[1,1]
    +(X-mu[0])*(Y-mu[1])*cov_inverse[0,1]
    +(Y-mu[1])*(X-mu[0])*cov_inverse[1,0]
))
#法1:matplotlib.pyplot.contourf
#法2:seaborn.heatmap

#法1
fig = plt.figure(2,figsize=(20,8))
ax = fig.add_subplot(121,title='analytical: ax.contourf')
ax.contourf(X,Y,Z,cmap='inferno',levels=points)
#法2
ax = fig.add_subplot(122,title='analytical: sns.heatmap')
#heatmap索引方向为“左上到右下”与传统“左下到右上”在竖直方向相反,在绘图时应在竖直方向翻转np.flip(Z,axis=0)
#横纵坐标拥挤,调整xticklabels, yticklabels至更大间隔
#cbar=Flase 关闭调色板
#square=True 将图像调整至正方形
sns.heatmap(np.flip(Z,axis=0),cmap="inferno",cbar=False,square=True,xticklabels=10,yticklabels=10)
plt.show()

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fanshaoliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值