Plot fitted curves

Is there anyway in Julia to fit these data represented in the attached figure?
I want to make them smooth curves (may be exponential fit).
datageneration

p1=plot!(dayss,numberofhealthyy,legend=false,color = :blue)
p2=plot!(dayss,numberofinfectedd,legend=false,color =:green)
p3=plot!(dayss,numberofrecoveredd,legend=false,color =  :gold )
p4=plot!(dayss,numberofsickk,legend=false,color =  :red)

A general principle for fitting functions: you need to decide what model to fit to - the best thing is if you have some inkling of what the underlying truth looks like. For instance I imagine these will be sums of logistic functions?

Once you know what model to fit, you can use something like the package LsqFit to fit it.

Kernel regression smoothing is a possibility. An unregistered function that will do it is https://github.com/mcreel/Econometrics/blob/main/src/NP/npreg.jl

2 Likes

Thanks for reply.
it is exponential fit
do you know how to write that using Lsqfit library?
I can not find clear example for exponential fit.!

Seems unlikely from the look of it, but for demonstration purposes:

model(x, p) = @. exp(p[1]*x + p[2]) # define a model function that takes an x-vector and a vector of fitting parameters
fit = curve_fit(model, xdata, ydata, [1.0, 1.0]) # the fourth argument is your best initial guess for `p`

@show fit.param # this is the found least-squares `p`
plot!(xdata, model(xdata, fit.param))
1 Like

Many thanks again for reply.
Is there any link or something to read from how to use different fitting functions?
Like how I know what is the best fit for my plots and what are the equations used ?

I’m a physicist, so this will be from that perspective, it might be different in other fields but:

It depends a bit on what you want to know about your data. The best way to choose is to know the answer a priori: If I throw a ball I know from Newtonian mechanics its trajectory should be a parabola,

model(x, p) = @. p[1] - p[2] * (x - p[3])^2

Performing this fit on a set of data points, I would be able to extract things like how hard the ball was thrown and what the local gravity acceleration is. It would not (unless I have some new physical understanding of the situation) be meaningful to fit these points to some kind of gaussian or lorentzian function. For one thing, the fit is likely to be poor, but with enough noise in the measurement I might not know that. For another, it becomes a lot less clear what it would mean to extract those parameters: in my parabolic model, g follows from p[2]. In a lorentzian model the relationship is a lot less obvious.

If you don’t know in advance, you can follow something called the smallest viable degree method. Here you’re cheating a bit by fitting a function, comparing it to your data, and increasing the complexity of your function until the fit is good without being overfitted. Works very well for polynomial model functions.

You can also look at the shape and, with some experience, make educated guesses as to what functions might fit: If it has three fix points, try a 3d degree polynomial. If it … looks gaussian: try a gaussian. Sigmoids (S-shaped curves like your blue and yellow ones) might be arctan functions, logistic functions or a myriad of others with discretely different properties.

In this case, my initial guess that you would want to try the logistic function was a combination of the methods above: Two of your curves look sigmoid, and a sigmoid in epidemiology is often a logistic map (from my very limited experience). If you can find one that fits, its parameters will map well to interesting characteristics like “growth rate”, “saturation level” and “inflection point”.

Try

model(x, p) = @. p[1]/(1 + exp(-p[2]*(x-p[3]))

p[3] here will be the x point halfway up the sigmoid, p[2] will be a measure of the growth rate, and p[1] will be the maximum. You can fit this to both the blue and yellow curve, where one will have a negative p[2]. The red curve should then be reasonably fitted by 100 - those two other curves.

1 Like