我的目标是计算通过一组点的平滑轨迹,如下所示.我已经看过了scipy.interpolate
和scipy user guide的可用方法.然而,对我来说, Select 正确的方法并不是很清楚.
它们之间的区别是什么
BSpline
,
splprep
,
splrep
,
UnivariateSpline
,
interp1d
,
make_interp_spline
及
CubicSpline
?
根据文献,所有的函数都是通过一系列的输入点来计算某个多项式样条函数.我应该 Select 哪种功能?A)三次样条和三次B样条有什么不同?B)splprep()
和splrep()
之间的区别是什么?C)为什么interp1d()
将被弃用?
我知道我在这里问了不同的问题,但我看不出把问题分开的意义,因为我假设答案是相关的.
总而言之,我发现scipy.interpolate模块的组织有些混乱.我想也许我不是唯一一个有这种印象的人,这就是为什么我要向他们伸出援手.
这就是我所走的路.下面是对一些测试数据运行不同的样条线函数的一些代码.它创建了下图.
- 我在某处读到过:"所有的三次样条线都可以表示为3阶B-样条线","这是一个视角问题,哪种表示法更方便".但是,如果我使用
CublicSpline
和任何一种B样条法,为什么我会得到不同的结果? - 我发现可以从
splprep
和splrep
的输出构造一个BSpline
对象,这样splev()
和BSpline()
的结果是等价的.这样,我们就可以将splrep
和splprep
的输出转换为scipy.interpolate()
的面向对象接口. -
splrep
、UnivariateSpline
和make_interp_spline
导致相同的结果.在我的2D数据中,我需要在每个数据维度上独立地应用插值.便利函数interp1d
也产生相同的结果.相关SO问题:Link -
splprep
和splrep
似乎没有关系.即使我 for each 数据轴单独计算两次splprep
(参见P0_NEW),结果看起来也不同.我在文档中看到,Splprep计算n-D曲线的B-Spline表示.但是,splrep
和splprep
是否应该没有关系呢? -
splprep
、splrep
和UnivariateSpline
具有平滑参数,而其他插值器没有此类参数. -
splrep
双,UnivariateSpline
双.然而,我找不到与splprep
相匹配的面向对象的版本.有吗?
import numpy as np
from scipy.interpolate import *
import matplotlib.pyplot as plt
points = [[0, 0], [4, 4], [-1, 9], [-4, -1], [-1, -9], [4, -4], [0, 0]]
points = np.asarray(points)
n = 50
ts = np.linspace(0, 1, len(points))
ts_new = np.linspace(0, 1, n)
(t0_0,c0_0,k0_0), u = splprep(points[:,[0]].T, s=0, k=3)
(t0_1,c0_1,k0_1), u = splprep(points[:,[1]].T, s=0, k=3)
p0_new = np.r_[np.asarray(splev(ts_new, (t0_0,c0_0,k0_0))),
np.asarray(splev(ts_new, (t0_1,c0_1,k0_1))),
].T
# splprep/splev
(t1,c1,k1), u = splprep(points.T, s=0, k=3)
p1_new = splev(ts_new, (t1,c1,k1))
# BSpline from splprep
p2_new = BSpline(t1, np.asarray(c1).T, k=k1)(ts_new)
# splrep/splev (per dimension)
(t3_0,c3_0,k3_0) = splrep(ts, points[:,0].T, s=0, k=3)
(t3_1,c3_1,k3_1) = splrep(ts, points[:,1].T, s=0, k=3)
p3_new = np.c_[splev(ts_new, (t3_0,c3_0,k3_0)),
splev(ts_new, (t3_1,c3_1,k3_1)),
]
# Bspline from splrep
p4_new = np.c_[BSpline(t3_0, np.asarray(c3_0), k=k3_0)(ts_new),
BSpline(t3_1, np.asarray(c3_1), k=k3_1)(ts_new),
]
# UnivariateSpline
p5_new = np.c_[UnivariateSpline(ts, points[:,0], s=0, k=3)(ts_new),
UnivariateSpline(ts, points[:,1], s=0, k=3)(ts_new),]
# make_interp_spline
p6_new = make_interp_spline(ts, points, k=3)(ts_new)
# CubicSpline
p7_new = CubicSpline(ts, points, bc_type="clamped")(ts_new)
# interp1d
p8_new = interp1d(ts, points.T, kind="cubic")(ts_new).T
fig, ax = plt.subplots()
ax.plot(*points.T, "o-", label="Original points")
ax.plot(*p1_new, "o-", label="1: splprep/splev")
ax.plot(*p2_new.T, "x-", label="1: BSpline from splprep")
ax.plot(*p3_new.T, "o-", label="2: splrep/splev")
ax.plot(*p4_new.T, "x-", label="2: BSpline from splrep")
ax.plot(*p5_new.T, "*-", label="2: UnivariateSpline")
ax.plot(*p6_new.T, "+-", label="2: make_interp_spline")
ax.plot(*p7_new.T, "x-", label="3: CubicSpline")
#ax.plot(*p8_new.T, "k+-", label="3: interp1d")
#ax.plot(*p0_new.T, "k+-", label="3: CubicSpline")
ax.set_aspect("equal")
ax.grid("on")
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.show()