如何生成等距插值

2024-06-14 04:49:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个不等距的(x,y)值列表。Here是这个问题中使用的存档。

我可以在值之间进行插值,但得到的不是等距插值点。我做的是:

x_data = [0.613,0.615,0.615,...]
y_data = [5.919,5.349,5.413,...]

# Interpolate values for x and y.
t = np.linspace(0, 1, len(x_data))
t2 = np.linspace(0, 1, 100)
# One-dimensional linear interpolation.
x2 = np.interp(t2, t, x_data)
y2 = np.interp(t2, t, y_data)

# Plot x,y data.
plt.scatter(x_data, y_data, marker='o', color='k', s=40, lw=0.)

# Plot interpolated points.
plt.scatter(x2, y2, marker='o', color='r', s=10, lw=0.5)

结果是:

enter image description here

可以看到,在图中原始点分布更密集的部分,红点更靠近。

我需要一种方法根据给定的步长值(比如0.1)在x,y中生成插值点等间距


正如askewchan所正确指出的,当我在x,y中的意思是“等间距时,我的意思是曲线中的两个连续插值点应该以相同的值彼此相距(欧几里德直线距离)。


我尝试了unubtu的答案,它对平滑曲线很有效,但对于不太平滑的曲线似乎会中断:

non-smooth-curve

这是因为代码以欧几里德方式而不是直接计算曲线上的点距离,我需要曲线上的距离在点之间是相同的。这个问题能解决吗?


Tags: 距离dataplotnpplt曲线marker插值
3条回答

下面的脚本将以相同的步骤x_max - x_min / len(x) = 0.04438插入点

import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt

data = np.loadtxt('data.txt')
x = data[:,0]
y = data[:,1]

f = interp1d(x, y)
x_new = np.linspace(np.min(x), np.max(x), x.shape[0])
y_new = f(x_new)

plt.plot(x,y,'o', x_new, y_new, '*r')
plt.show()

enter image description here

我们先来考虑一个简单的例子。假设你的数据看起来像蓝线, 下面。

enter image description here

如果要选择相距r的等距点, 那么r就有了一些临界值,其中(1,2)处的尖点是第一个等距点。

如果你想要的点要比这个临界距离大,那么 第一个等距点会从(1,2)跳到非常不同的地方-- 由绿色弧线和蓝色直线的交点描绘。这种变化不是渐进的。

这个玩具案例表明,参数r的微小变化可能对解产生根本的、不连续的影响。

它还建议你必须知道第i个等距点的位置 才能确定第(i+1)等距点的位置。

因此,似乎需要迭代求解:

import numpy as np
import matplotlib.pyplot as plt
import math

x, y = np.genfromtxt('data', unpack=True, skip_header=1)
# find lots of points on the piecewise linear curve defined by x and y
M = 1000
t = np.linspace(0, len(x), M)
x = np.interp(t, np.arange(len(x)), x)
y = np.interp(t, np.arange(len(y)), y)
tol = 1.5
i, idx = 0, [0]
while i < len(x):
    total_dist = 0
    for j in range(i+1, len(x)):
        total_dist += math.sqrt((x[j]-x[j-1])**2 + (y[j]-y[j-1])**2)
        if total_dist > tol:
            idx.append(j)
            break
    i = j+1

xn = x[idx]
yn = y[idx]
fig, ax = plt.subplots()
ax.plot(x, y, '-')
ax.scatter(xn, yn, s=50)
ax.set_aspect('equal')
plt.show()

enter image description here

注意:我将纵横比设置为'equal',以使点更明显地等距。

将xy数据转换为参数化曲线,即计算点之间的所有距离,并通过累积求和在曲线上生成坐标。然后根据新的坐标独立地插入x和y坐标。

import numpy as np
from pylab import plot

data = '''    0.613   5.919
    0.615   5.349
    0.615   5.413
    0.617   6.674
    0.617   6.616
    0.63    7.418
    0.642   7.809
    0.648   8.04
    0.673   8.789
    0.695   9.45
    0.712   9.825
    0.734   10.265
    0.748   10.516
    0.764   10.782
    0.775   10.979
    0.783   11.1
    0.808   11.479
    0.849   11.951
    0.899   12.295
    0.951   12.537
    0.972   12.675
    1.038   12.937
    1.098   13.173
    1.162   13.464
    1.228   13.789
    1.294   14.126
    1.363   14.518
    1.441   14.969
    1.545   15.538
    1.64    16.071
    1.765   16.7
    1.904   17.484
    2.027   18.36
    2.123   19.235
    2.149   19.655
    2.172   20.096
    2.198   20.528
    2.221   20.945
    2.265   21.352
    2.312   21.76
    2.365   22.228
    2.401   22.836
    2.477   23.804'''

data = np.array([line.split() for line in data.split('\n')],dtype=float)

x,y = data.T
xd =np.diff(x)
yd = np.diff(y)
dist = np.sqrt(xd**2+yd**2)
u = np.cumsum(dist)
u = np.hstack([[0],u])

t = np.linspace(0,u.max(),20)
xn = np.interp(t, u, x)
yn = np.interp(t, u, y)

plot(x,y,'o')
plot(xn,yn,'gs')
xlim(0,5.5)
ylim(10,17.5)

相关问题 更多 >