Python 在np.meshgrid的截面中标记点
我试图根据x点和y点位于python中网格网格的特定部分来标记它们。这些点存储在数据框中 这里我有一个坐标的散点图,在上面我绘制了网格。 整个网格更大,从左下角点(5001250)到右上角点(27503250),这意味着整个网格是225x200个截面 我想遍历网格的各个部分,并检查点是否在其中。如果某个点位于剖面内,我希望向该点添加标签。标签应与节名称相同。 我想在数据框中添加一个名为“section”的列,该列存储点所属的部分 在示例(上图)中,我想用Python 在np.meshgrid的截面中标记点,python,pandas,numpy,matplotlib,Python,Pandas,Numpy,Matplotlib,我试图根据x点和y点位于python中网格网格的特定部分来标记它们。这些点存储在数据框中 这里我有一个坐标的散点图,在上面我绘制了网格。 整个网格更大,从左下角点(5001250)到右上角点(27503250),这意味着整个网格是225x200个截面 我想遍历网格的各个部分,并检查点是否在其中。如果某个点位于剖面内,我希望向该点添加标签。标签应与节名称相同。 我想在数据框中添加一个名为“section”的列,该列存储点所属的部分 在示例(上图)中,我想用 770由于所有的点大小相同,因此无需事
770由于所有的点大小相同,因此无需事先定义所有的方块,然后确定哪些方块有哪些点。我将使用每个点的坐标直接确定它将落在哪个正方形中 为了简单起见,让我们以一维为例。您希望将数字线上的点编组为“正方形”(实际上是一维线段)。如果第一个正方形从x=0开始,第二个正方形从x=10开始,第三个正方形从x=20开始,依此类推,那么如何找到任意点x的正方形?你知道你的正方形的间距是10(你知道它们从0开始,这使事情变得更容易),所以你可以简单地除以10并向下取整得到正方形索引 在三维(或n维)中也可以轻松地完成同样的事情
square\u side=10
x_min=df['x[mm]'].min()
y_min=df['y[mm]'].min()
def标签_点(x,y):
#双正斜杠是整数(向下舍入)除法
#如果确实需要基于1的索引,请在此处添加1
x_标签=(x-x_最小值)//正方形
y_label=chr(ord('A')+(y-y_min)//方边)
返回f'{y_label}{x_label}'
df['label']=df['X[mm]','Y[mm]']]。应用(lambda坐标:label_点(*坐标),轴=1)
至于效率,此解决方案只对每个点进行一次检查,并且对每个点进行恒定量的工作,因此点数为O(n)。你的解决方案看每个正方形一次,每个正方形看每个点,这是O(n×m),其中n是点的数量,m是正方形的数量
您的解决方案更一般,因为当矩形网格具有任意旋转时,is_inside_rect
函数可以工作。在这种情况下,我建议围绕原点旋转所有点,然后运行我的解决方案
同样,你的循环在每个循环的x和y上加上10,所以你是在对角遍历你的空间。我想你不是有意的。谢谢。我尝试了这个,但我得到了TypeError:('label_point()接受了2个位置参数,但给出了887323','发生在索引X[mm])@FedericaTomola抱歉,您需要
中的axis=1
。apply()
谢谢它现在可以工作了
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
df = pd.read_csv('./file.csv', sep=';')
x_min = df['X[mm]'].min()
x_max = df['X[mm]'].max()
y_min = df['Y[mm]'].min()
y_max = df['Y[mm]'].max()
#side of the square in mm:
square_side = 10
xs = np.arange(x_min, x_max+square_side, square_side)
ys = np.arange(y_min, y_max+square_side, square_side)
x_2, y_2 = np.meshgrid(xs, ys, indexing = 'ij')
fig, ax = plt.subplots(figsize=(9,9))
ax.plot(df['X[mm]'], df['Y[mm]'], linewidth=0.2, c='black')
#plot meshgrid as grid instead of points:
segs1 = np.stack((x_2[:,[0,-1]],y_2[:,[0,-1]]), axis=2)
segs2 = np.stack((x_2[[0,-1],:].T,y_2[[0,-1],:].T), axis=2)
plt.gca().add_collection(LineCollection(np.concatenate((segs1, segs2))))
ax.set_aspect('equal', 'box')
plt.show()
def is_inside_rect(M, A, B, D):
'''Check if a point M is inside a rectangle with corners A, B, C, D'''
# 0 <= dot(BC,BM) <= dot(BC,BC)
#print(np.dot(B - A, D - A))
return 0 <= np.dot(B - A, M - A) <= np.dot(B - A, B - A) and 0 <= np.dot(D - B, M - B) <= np.dot(D - B, D - B)
x = x_min
y = y_min
while (x <= x_max + square_side) and (y <= y_max + square_side):
A = np.array([x, y])
B = np.array([x + square_side, y])
D = np.array([x + square_side, y + square_side])
print(A, B, D)
df['c'] = df[['X[mm]', 'Y[mm]']].apply(lambda coord: 'red' if is_inside_rect(np.array(coord), A, B, D) else 'black', axis=1)
x += square_side
y += square_side