使用Scipy库函数查找最近邻点并作可视化

scipy.spatial中的cKDTree类可以将坐标点集合根据与某位置的距离按从小到大的顺序排序,返回他们的下标以及具体的距离值。根据这个特性,可以查找某个点的最近邻点。

 

下面的代码,首先随机生成10个二维坐标点,然后使用plt.scatter标出他们的位置。然后在一个for循环中依次查找出与他们最近的点(自身除外),并在两者之间使用plt.arrow添加一个带箭头的连线。最后在连线的中心处使用plt.text标注这个距离值。

图中出现了一些双向箭头,是因为他们互相为对方的最近邻。

import scipy.spatial as spt
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='simhei', size=10)    # 设置中文显示,字体大小
plt.rc('axes', unicode_minus=False)         # 该参数解决负号显示的问题


points = np.random.randint(1,20,(10,2))  # 生成10个二维坐标点,x和y的取值范围为[1,20)
plt.scatter(x=points[:, 0], y=points[:, 1], s=150 ,color='red', marker='o')   # 标出所有样本点   s代表marker的大小  注意前两个参数,不是坐标点,而是x坐标的集合(二维矩阵points的第一列)和y坐标的集合(二维矩阵points的第二列)

# 执行查找函数
tree = spt.cKDTree(data=points)  

for point in points:
    distances, indexs = tree.query(point, k=2)  # 对每个坐标点,求出与它距离最近的两个点(最近邻是它本身,要忽略掉)
    print('距离点{}最近的坐标点是{},距离为{:.2f}'.format(point,points[indexs[1]],distances[1]))
    # point代表当前点,point[0]即为当前点的x坐标,point[1]即为当前点的y坐标
    # points[indexs[1]]代表其他点中距离当前点最近的一个点,points[indexs[1]][0]和points[indexs[1]][1]代表这个点的x和y坐标
    x = [point[0], points[indexs[1]][0]]
    y = [point[1], points[indexs[1]][1]]
    # plt.plot( x,y, color='black')    # 不带箭头的连线。注意前两个参数,不是坐标点,而是x坐标的集合和y坐标的集合
    plt.arrow( x= point[0],y= point[1], dx=points[indexs[1]][0]-point[0],  dy=points[indexs[1]][1]-point[1] ,width=0.1 ,length_includes_head=True, color='green')    # 带箭头的连线:https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.arrow.html 
    plt.text(sum(x)/2, sum(y)/2,fontsize=10, s="%.2f"%distances[1])  # 在连线上标明最短距离的值。因为x是两个点x坐标的集合,所以sum(x)/2代表这条线的中心位置,在中间写   (s表示要书写的字符串)

plt.show() # 展示图像

 

 

程序的运行结果:

1. 输出

使用Scipy库函数查找最近邻点并作可视化_第1张图片

 

2.可视化

使用Scipy库函数查找最近邻点并作可视化_第2张图片


你可能感兴趣的:(python算法机器学习)