我也是Python的新手,但最近我的搜索让我找到了一个非常有用的scipy插值教程。从我对此的阅读中,我认为BivariateSpline类/函数族旨在插值3D表面而不是3D曲线。
对于我的3D曲线拟合问题(我认为与您的非常相似,但还想平滑噪声),我最终使用了scipy.interpolate.splprep(不要与scipy.interpolate.splrep混淆)。从上面链接的教程中,您正在寻找的样条系数由splprep返回。
正常输出是一个3元组(t,c,k),其中包含结点t,系数c和样条的阶数k。
文档将这些过程函数称为“较旧的、非面向对象的FITPACK包装”,与“较新的、面向对象的”UnivariateSpline和BivariateSpline类形成对比。我本人更喜欢“较新的、面向对象的”方式,但据我所知,UnivariateSpline只处理1-D情况,而splprep直接处理N-D数据。以下是我用来测试这些函数的简单测试案例:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
from mpl_toolkits.mplot3d import Axes3D
total_rad = 10
z_factor = 3
noise = 0.1
num_true_pts = 200
s_true = np.linspace(0, total_rad, num_true_pts)
x_true = np.cos(s_true)
y_true = np.sin(s_true)
z_true = s_true/z_factor
num_sample_pts = 80
s_sample = np.linspace(0, total_rad, num_sample_pts)
x_sample = np.cos(s_sample) + noise * np.random.randn(num_sample_pts)
y_sample = np.sin(s_sample) + noise * np.random.randn(num_sample_pts)
z_sample = s_sample/z_factor + noise * np.random.randn(num_sample_pts)
tck, u = interpolate.splprep([x_sample,y_sample,z_sample], s=2)
x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck)
u_fine = np.linspace(0,1,num_true_pts)
x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck)
fig2 = plt.figure(2)
ax3d = fig2.add_subplot(111, projection='3d')
ax3d.plot(x_true, y_true, z_true, 'b')
ax3d.plot(x_sample, y_sample, z_sample, 'r*')
ax3d.plot(x_knots, y_knots, z_knots, 'go')
ax3d.plot(x_fine, y_fine, z_fine, 'g')
fig2.show()
plt.show()
![output plot](https://istack.dev59.com/5tI3n.webp)