matplotlib seaborn 数据可视化(2)——2维数据平面直方图(伪等高图)
随机数据
二维正态分布
y=12π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=Σ=[10.80.81],mu=μ=[−11]\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=[x1−μ1x2−μ2]⊤[cov(x1,x1)cov(x1,x2)cov(x2,x1)cov(x1,x2)]−1[x1−μ1x2−μ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()
运行结果:

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)