How to plot a best fit curve in Julia when the data is a time series?

This is a copy of my question here on Stack Overflow (unanswered at the time of writing).

I’m trying to plot some measurements over time with a best-fit curve, using Julia’s plotting tools. There’s already a fairly good answer how to do this with a simple numeric data series:

Julia: How to find best fit curve / equation when I have a plot?

However, these tools (well - at least the Polynomials package) do not like being given Date values. I imagine some sort of conversion from Dates into a numeric value needs to be done, but I want the resulting plots to retain their scales in date units, which would need a conversion back again.

I suspect this is a fairly common problem and there must be an elegant way to solve it, but being new to Julia I would like to ask for some pointers to what a good solution looks like?

2 Likes

I don’t think there is a package doing what you want. If you don’t mind the conversion, you need to do it only once, to do the fit; you plot against the original date values:

using LsqFit: curve_fit
using Plots

Date2Val(x::DateTime) = x.instant.periods.value # DateTime to value converter
m(t, p) = p[1] * exp.(p[2] * t)                 # the model
dt = sort(DateTime.(2022, 4, 11, 1, 30, rand(1:30, 15)),
          rev=true)                             # generate random DateTime values and sort them from earlier to later
x = Date2Val.(dt) .- Date2Val(dt[end])          # convert DateTime to a numerical value
y = m(x, [1, -1e-4]) + 1e-2randn(length(dt))    # generate the y values and add some noise
fit = curve_fit(m, x, y, [1.4, -1e-2])          # do the least square fit using LsqFit
scatter(dt, y, label="data")                    # plot data ...
plot!(dt, m(x, fit.param), label="fit")         # ... and fit both agains dates

image

2 Likes

Thanks! I think that does the job nicely.