Matplotlib散点图绘制异常排查:为何高于阈值的点呈现矩形而非预期圆形?
问题排查与优化:高斯阈值散点图从矩形变圆形
问题原因分析
咱们来拆解一下为什么会得到矩形分布的点——核心问题出在循环里的索引取值错误!
你通过meshgrid生成的X和Y都是100x100的二维数组:
X[i]对应的是第i行的所有x值(一整行都是同一个x坐标)Y[j]对应的是第j列的所有y值(一整列都是同一个y坐标)
当判断Z[i][j] > eps成立时,你把一整行的x值和一整列的y值都追加到了结果数组里,这就导致最终的点集覆盖了一个矩形区域,而不是符合高斯函数等高线的圆形。
修复方案1:修正循环索引取值
只需要把循环里的X[i]和Y[j]改成X[i][j]和Y[i][j],就能正确提取单个点的坐标:
import matplotlib.pyplot as plt import numpy as np fig = plt.figure() eps = 0.8 X = np.linspace(-1, 1, 100) Y = np.linspace(-1, 1, 100) X, Y = np.meshgrid(X, Y) Z = np.exp(-X**2 - Y**2) data_zero_x = np.array([]) data_zero_y = np.array([]) for i in range(len(X)): for j in range(len(Y)): if Z[i][j] > eps: # 提取二维数组中对应位置的单个元素 data_zero_x = np.append(data_zero_x, X[i][j]) data_zero_y = np.append(data_zero_y, Y[i][j]) plt.scatter(data_zero_x, data_zero_y) plt.show()
更优方案2:使用Numpy向量化操作(推荐)
嵌套循环在处理大数据时效率很低,Numpy的向量化操作可以帮我们更简洁高效地完成筛选:
import matplotlib.pyplot as plt import numpy as np fig = plt.figure() eps = 0.8 X = np.linspace(-1, 1, 100) Y = np.linspace(-1, 1, 100) X, Y = np.meshgrid(X, Y) Z = np.exp(-X**2 - Y**2) # 创建布尔掩码,标记所有满足阈值条件的位置 mask = Z > eps # 提取掩码对应的x、y坐标,用ravel()将二维数组展平为一维 filtered_x = X[mask].ravel() filtered_y = Y[mask].ravel() plt.scatter(filtered_x, filtered_y) plt.show()
这种方式完全避开了循环,利用Numpy的广播机制和数组索引特性,代码更简洁,运行速度也会快很多(尤其是当样本量增大时,性能提升会非常明显)。
内容的提问来源于stack exchange,提问作者JoeGlas
相关产品推荐
相关产品推荐

