基于点间距离着色的Matplotlib散点图实现问询
基于点间平均距离的Matplotlib散点图着色方案
问题解答
Matplotlib没有直接实现“按点间平均距离自动着色”的现成函数,需要自定义计算逻辑,但可以借助numpy的向量化运算实现高效计算,完全避免低效的逐点循环。
高效计算方案
核心思路是利用numpy广播特性批量计算点对距离,再快速统计每个点的平均距离,步骤如下:
- 将每组点的x、y坐标合并为二维数组(shape=(n, 2))
- 批量计算所有点对的欧氏距离,生成距离矩阵
- 计算每个点到其他所有点的平均距离(排除自身的0距离)
- 将平均距离归一化到[0,1]区间,作为颜色映射的输入值
完整代码实现
import matplotlib.pyplot as plt import numpy as np def compute_avg_distances(x, y): # 合并坐标为二维数组 points = np.column_stack((x, y)) # 用广播计算所有点对的坐标差 diffs = points[:, np.newaxis, :] - points[np.newaxis, :, :] # 计算欧氏距离矩阵 dist_matrix = np.sqrt(np.sum(diffs ** 2, axis=-1)) # 计算每个点的平均距离(排除自身距离,即对角线的0) avg_distances = (dist_matrix.sum(axis=1) - np.diag(dist_matrix)) / (len(points) - 1) # 归一化到[0,1]区间 normalized_dists = (avg_distances - avg_distances.min()) / (avg_distances.max() - avg_distances.min()) return normalized_dists # 第一组数据 x1 = np.array([1,3,4,6,7,9,10,11,13,14,15]) y1 = np.array([1,3,4,6,7,9,10,11,13,14,15]) norm_dists1 = compute_avg_distances(x1, y1) # 第二组数据 x2 = np.array([6,7,8,9,10,11,12,13,14,15]) y2 = np.array([1,4,7,10,13,16,19,22,25,28]) norm_dists2 = compute_avg_distances(x2, y2) # 绘制散点图 plt.figure(figsize=(10,6)) # 第一组:平均距离最小(密集区)对应Reds最亮,最大对应最深 scatter1 = plt.scatter(x1, y1, c=norm_dists1, cmap='Reds', s=100, alpha=0.8) # 第二组同理 scatter2 = plt.scatter(x2, y2, c=norm_dists2, cmap='Reds', s=100, alpha=0.8) # 添加颜色条,标注含义 plt.colorbar(scatter1, label='归一化平均距离(值越小,点越密集)') plt.xlabel('X参数') plt.ylabel('Y参数') plt.title('基于点间距离的散点图着色') plt.legend(['第一组数据', '第二组数据']) plt.show()
针对核心目标的调整
你的核心需求是用颜色区分参数关系的强弱:
- 若要密集区(平均距离小)用亮色,直接使用上述代码的
c=norm_dists1即可(Reds色卡中0对应最浅亮色,1对应最深暗色) - 若要密集区用深色,只需将颜色参数改为
c=1 - norm_dists1,这样密集点对应色卡的深色,稀疏点对应浅色
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

