How to smooth a zig-zag-line with only a few points?
I have read the following topics here in this forum:
smoothing-interpolation-for-tachometer-data
smoothing-data-with-dates
But I am still struggling with my sort of zig-zag-lines. I achieved the best results so far with the package bsplinekit
, but the result is still not what I am looking for.
Any ideas? Here my BSplineKit.jl
-example:
begin
using PlotlyJS
using BSplineKit, LinearAlgebra, SparseArrays
# ---
case_ = 1
if case_ == 1 # real data
x_in = [0.114, 0.112, 0.11, 0.107, 0.105, 0.103, 0.102, 0.0998, 0.0983, 0.097, 0.0969, 0.094, 0.0935, 0.0928,
0.0928, 0.0917, 0.093, 0.0918, 0.092, ]
y_in = [-0.0126, -0.0116, -0.0119, -0.0113, -0.0106, -0.00912, -0.00981, -0.0089, -0.00685, -0.00702, -0.00574,
-0.00603, -0.00516, -0.00431, -0.00328, -0.00135, -0.000356, -0.000367, 0.00181,]
elseif case_ == 2 # synthetic data
x_in = collect(1:1.0:10000)
y_in = [x^1.35 + x*rand() for x in 1:length(x_in)]
else
error("Case not defined!")
end
end
# ---
begin
# --- code taken from:
# --- https://discourse.julialang.org/t/smoothing-interpolation-for-tachometer-data/56117/20
n_breakpoints = 4
spline_order = 3 # order = 4 is equal to cubic splines
# Create B-spline basis of "spline_order" order (spline_order = 4 <=> cubic splines) with chosen breakpoints
xbreaks = LinearAlgebra.LinRange(extrema(x_in)..., n_breakpoints)
B_ = BSplineBasis(BSplineOrder(spline_order), xbreaks)
# Construct spline from the given data by @jipolanco
C_ = BSplineKit.collocation_matrix(B_, x_in, SparseMatrixCSC{Float64}) # evaluates basis functions at data points
coefs = LinearAlgebra.qr(C_) \ y_in # spline coefficients
fspline = BSplineKit.Spline(B_, coefs)
y_smoothed = fspline.(x_in)
# --- plot:
fn_ = joinpath(raw"C:\tmp\plt", string("smoothing_spline_order_", spline_order, ".svg"))
fig_hdl = PlotlyJS.Plot([PlotlyJS.scatter(; x= x_in, y= y_in, name= "data", mode= "markers+lines"),
PlotlyJS.scatter(; x= x_in, y= y_smoothed, name= "smoothed")],
PlotlyJS.Layout(;title_text = string("Data Points: ", length(x_in), ", Break Points: ", n_breakpoints,
", Spline Order: ", spline_order)) )
PlotlyJS.savefig(fig_hdl, fn_)
end