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. 输出
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。