Description
csaps.CubicSmoothingSpline purports to support periodic functions, but does not implement this correctly.
I believe this is because it is a smoothing spline, which means that there are far more knots stored than "effective knots" due to smoothing. This means that when the periodic function is used by the underlying scipy implementation, which likely only looks at the first and last knots, you get a sharp discontinuity.
This is all purely speculation!
A not-brilliant-fix is to repeat your data -1 and +1 period and fit just the usual (non-periodic) smoothed spline to this. There will not be any huge discontinuity, but this does not guarantee that your endpoints will match exactly, so it's better but not perfect. Note that you can't have identical x values in your input, so you need to offset very slightly, or average your endpoints.
The correct solution is probably to have the smoother correctly consider periodic functions, either when you generate the smoother with CubicSmoothingSpline() which would require an additional parameter for periodic functions, or re-implementing the underlying scipy for interpolating/extrapolating (which is probably more work).
You can test this with the following code:
import numpy as np
import matplotlib.pyplot as plt
from csaps import csaps
np.random.seed(1234)
x = np.linspace(-5., 5., 25)
y = np.exp(-(x/2.5)**2) + (np.random.rand(25) - 0.2) * 0.3
smoother = csaps(x, y, smooth=0.85)
xs = np.linspace(-6.5, 6.5, 100)
ys = smoother(xs)
ys_periodic = smoother(xs, extrapolate='periodic')
better_smoother = csaps(np.r_[x-10.001,x,x+10.001], np.r_[y,y,y], smooth=0.85)
ys_better = better_smoother(xs)
plt.plot(x, y, 'o', xs, ys, '-', xs, ys_periodic, '-', xs, ys_better, '-')
plt.show()
print("non-periodic", smoother([-5,5]))
print("periodic",smoother([-5,5], extrapolate='periodic'))
print("better, but not perfect",better_smoother([-5,5]))