随机数据
二维正态分布
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()
运行结果: