我有一个复杂的曲线定义为表中的一组点,如此(完整的表是here):
# x y
1.0577 12.0914
1.0501 11.9946
1.0465 11.9338
...
如果我使用命令绘制此表:
plt.plot(x_data, y_data, c='b',lw=1.)
plt.scatter(x_data, y_data, marker='o', color='k', s=10, lw=0.2)
我得到以下内容:
我手动添加红点和段的地方 . 我需要的是一种计算每个点的那些段的方法,即:找到从该2D空间中的给定点到插值曲线的最小距离的方法 .
我不能使用到数据点本身的距离(产生蓝色曲线的黑点),因为它们不是以相等的间隔定位,有时它们是接近的,有时它们相距很远,这深深地影响了我的结果 . 线 .
由于这不是一个表现良好的曲线,我尝试使用UnivariateSpline进行内插,但它返回非常差的拟合:
# Sort data according to x.
temp_data = zip(x_data, y_data)
temp_data.sort()
# Unpack sorted data.
x_sorted, y_sorted = zip(*temp_data)
# Generate univariate spline.
s = UnivariateSpline(x_sorted, y_sorted, k=5)
xspl = np.linspace(0.8, 1.1, 100)
yspl = s(xspl)
# Plot.
plt.scatter(xspl, yspl, marker='o', color='r', s=10, lw=0.2)
我也试过增加插值点的数量但是弄得一团糟:
# Sort data according to x.
temp_data = zip(x_data, y_data)
temp_data.sort()
# Unpack sorted data.
x_sorted, y_sorted = zip(*temp_data)
t = np.linspace(0, 1, len(x_sorted))
t2 = np.linspace(0, 1, 100)
# One-dimensional linear interpolation.
x2 = np.interp(t2, t, x_sorted)
y2 = np.interp(t2, t, y_sorted)
plt.scatter(x2, y2, marker='o', color='r', s=10, lw=0.2)
任何想法/指针将不胜感激 .
3 回答
如果您愿意使用库,请查看
shapely
:https://github.com/Toblerity/Shapely作为一个简单示例(
points.txt
包含您在问题中链接的数据):作为一个交互式示例(这也绘制了您想要的线段):
请注意,我添加了
ax.axis('equal')
.shapely
在数据所在的坐标系中运行 . 如果没有等轴图,视图将失真,而shapely
仍然会找到最近的点,它在显示中看起来不太正确:曲线本质上是参数的,即对于每个x,不需要唯一的y,反之亦然 . 所以你不应该插入y(x)或x(y)形式的函数 . 相反,你应该做两个插值,x(t)和y(t),其中t是相应点的索引 .
然后使用
scipy.optimize.fminbound
找到最优t,使得(x(t) - x0)^ 2(y(t) - y0)^ 2最小,其中(x0,y0)是第一个图中的红点 . 对于fminsearch,您可以指定t的最小/最大边界为1
和len(x_data)
您可以尝试在曲线上的增量点对上实现点到线距离的计算,并找到最小值 . 这将从绘制的曲线中引入一点误差,但它应该非常小,因为这些点相对靠近在一起 .
http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line