python - 如何将等高线图限制为二维高斯的 3sigma 变化?
问题描述
我对绘制二维高斯分布的等高线图有点好奇。在我的例子中,对于一组给定的 2D 点,我将它们聚集到不同的网格单元中,并计算每个单元的协方差矩阵,并绘制每个单元的高斯分布。当我绘图时,我不想要单元格的整个轮廓,但分布限制在数据点的 3 sigma 内。无论如何它可以做到吗?
我的代码如下:
import numpy as np
import matplotlib.pyplot as plt
def createCells():
partition = 4
coords = [np.linspace(-1.0 , 1.0, num = partition + 1) for i in range(2)]
x, y = np.meshgrid(*coords)
return x, y
def probab(mean, covMat, lPoints):
lPoints = lPoints[..., np.newaxis] if lPoints.ndim == 2 else lPoints ## Create vectorized values for the x, y
if np.linalg.det(covMat) > 0:
factor1 = (2*np.pi)*(np.linalg.det(covMat)**(-1/2))
factor2 = np.exp((-1/2)*np.einsum('ijk,jl,ilk->ik', lPoints - mean, np.linalg.inv(covMat), lPoints - mean))
return factor1*factor2
if __name__ == '__main__':
points = np.array([[-0.35, -0.15], [0.1, 0.1], [-0.1, 0.1], [0.05, 0.05],[0.25, 0.05], [0.1, 0.15], [0.1, 0.2], [-0.2, -0.2], [-0.25, 0.25], [0.45, 0.45], [0.75, 0.75], [0.6, 0.6], [0.55, 0.55], [0.7, 0.7], [0.68, 0.73]])
x1, y1 = createCells()
x = x1[0]
y = y1[:,0]
lP = np.array([])
numberOftimes = 0
for i in range(len(x) - 1):
for j in range(len(y) - 1):
count = 0
meanX = 0.0
meanY = 0.0
localPoints = []
covMat1 = np.array([])
covMat2 = np.array([])
for point in points:
inbetween_x = x[i] <= point[0] <= x[i + 1]
inbetween_y = y[j] <= point[1] <= y[j + 1]
if inbetween_x and inbetween_y:
count += 1
meanX += point[0]
meanY += point[1]
localPoints.append([point[0], point[1]])
if count >= 2:
numberOftimes += 1
#print(f"The local points are {localPoints}")
localPoints = np.array(localPoints)
meanX /= count
meanY /= count
meanXY = np.array([meanX, meanY])
#print(meanXY.shape)
#print(localPoints.shape)
lP = localPoints - meanXY
for k in range(count):
lPtranspose = (np.array([lP[k]])).T
lPCurrent = (np.array([lP[k]]))
if len(covMat1) > 0:
covMat1 += lPtranspose.dot(lPCurrent)
else:
covMat1 = lPtranspose*lP[k]
covMat1 /= count
lPoints = localPoints[..., np.newaxis] if lP.ndim == 2 else lP ## Create vectorized values for the x, y
meanXY1 = localPoints.mean(0)
meanXY2 = lPoints.mean(0)
covMat3 = np.einsum('ijk, ikj->jk', lPoints - meanXY2, lPoints - meanXY2) / lPoints[0] - 1
#yamlStatus = self.savingYaml(i, j, meanXY, covMat3) ## To store the cell parameters in a yaml file (for now its just out of scope for the question)
if np.linalg.det(covMat3) > 0: #compute the probability only if the det is not 0
Xx = np.linspace(x[i], x[i + 1], 1000)
Yy = np.linspace(y[i], y[i + 1], 1000)
Xx,Yy = np.meshgrid(Xx, Yy)
lPoints = np.vstack((Xx.flatten(), Yy.flatten())).T
pos = np.empty(Xx.shape + (2,))
pos[:, :, 0] = Xx
pos[:, :, 1] = Yy
z2 = probab(meanXY2, covMat3, lPoints)
summed = np.sum(z2)
z2 = z2.reshape(1000, 1000)
cs = plt.contourf(Xx, Yy, z2)#, cmap=cm.viridis)
plt.clabel(cs)
localPoints = []
#print(f"The number of times count is greater than 1 is {numberOftimes}")
plt.plot(x1, y1, marker='.', linestyle='none', markersize=20)
plt.plot(points[:,0 ], points[:, 1], marker='.', linestyle='none', markersize=10)
plt.grid(linewidth=0.5)#abs(x1[0][0]-y1[0][0]))
plt.show()
解决方案
推荐阅读
- c - 整数之和,不包括 13 和 13 之后的数字
- google-sheets - 如果文本包含数字,谷歌电子表格条件格式
- arrays - 如何在一组坐标中找到最大的 x,y 坐标?
- sql - 使用 Oracle REGEXP_SUBSTR 提取下划线分隔的大写数据
- r - 如何在 r 中的多行上迭代地使用 mutate
- sql - 将 VARCHAR 转换为 XML,包括 < (<) , > (>)
- php - Laravel 中的 MethodNotAllowedHttpException,Request::isMethod('') 不起作用
- javascript - 使用数组将动态添加的 li 和 ul 元素保存到数据库
- python - 使用多处理写入多个文件。错误:“TypeError:无法序列化 '_io.TextIOWrapper' 对象”
- docker - 如何设置 docker date 并确保它不与我的系统时间同步?