scipy BSpline fitting in python

Sophia Medallon picture Sophia Medallon · Jul 19, 2017 · Viewed 13.9k times · Source

This is my first time using BSpline, and I want to fit a curve to my data points. I've tried using Univariate Spline and attempted to use splev and splrep but I'd really like to learn how to do this using BSpline.

It looks like my fitting is really choppy and the line isn't even going through the points.

arraymagU = linspace(U_timeband.min(),U_timeband.max(),300) #array for my x data points
UfunctionBS = BSpline(U_timeband,U_magband,k=4,extrapolate=False)
arraymagU2 = UfunctionBS(arraymagU)

plt.plot(arraymagU,arraymagU2)

U_timeband is my x coordinates and U_magband is simply my y. k=4 I think indicates a cubic fit? I've played around with that value and it doesn't seem to make it better.

It produces this:

this

How can I make this better, consistent? I think I may have to define breakpoints, but I'm not sure how to do that either.

Answer

unutbu picture unutbu · Jul 19, 2017

splrep returns a tuple (t,c,k) containing the vector of knots, the B-spline coefficients, and the degree of the spline. These can be fed to interpolate.BSpline to create a BSpline object:

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

x = np.array([ 0. ,  1.2,  1.9,  3.2,  4. ,  6.5])
y = np.array([ 0. ,  2.3,  3. ,  4.3,  2.9,  3.1])

t, c, k = interpolate.splrep(x, y, s=0, k=4)
print('''\
t: {}
c: {}
k: {}
'''.format(t, c, k))
N = 100
xmin, xmax = x.min(), x.max()
xx = np.linspace(xmin, xmax, N)
spline = interpolate.BSpline(t, c, k, extrapolate=False)

plt.plot(x, y, 'bo', label='Original points')
plt.plot(xx, spline(xx), 'r', label='BSpline')
plt.grid()
plt.legend(loc='best')
plt.show()

enter image description here