How do I plot a curved best fit line of the data below? Using fitnlm has been recommended.

3 views (last 30 days)
time_1 = [-0.0151 0.0908 0.3177 0.9834 1.9062 3.3132 4.8563 6.6263 9.1074 9.9697]; conc_1 = [0.9975 0.7146 0.5062 0.2581 0.1266 0.0546 0.0223 -0.0025 0 -0.0199];
figure plot(time_1,conc_1) title('Data Set 1') xlabel('Time') ylabel('Concentration')

Answers (1)

John D'Errico
John D'Errico on 3 Apr 2018
fitnlm will do nothing, UNLESS you have a model. And if you have no clue as to what model is appropriate, then the first thing you would need to do is choose a model.
The problem is, fitnlm is not intelligent, able to choose an appropriate model, as well as fit it.
When you have absolutely no inteligent choice of model, the very first thing you need to do is run a spline through it. A simple interpolating spline is not terrible.
tinterp = linspace(min(time_1),max(time_1),100);
cinterp = interp1(time_1,conc_1,tinterp,'spline');
plot(time_1,conc_1,'ro',tinterp,cinterp,'b-')
gridon
It looks a little bumpy. If conc_1 is concentration, then I would not believe that it goes negative. Negative concentrations don't make much sense. I also don't know what you expect for noise on this data. Is this noise in your data, or is it signal?
As far as a nonlinear model goes, the logical choice would be a negative exponential. I'll use the curve fitting toolbox here, as it is simpler to build a model.
ft = fittype('exp1')
ft =
General model Exp1:
ft(a,b,x) = a*exp(b*x)
mdl = fit(time_1',conc_1',ft,'startpoint',[1 -2])
mdl =
General model Exp1:
mdl(x) = a*exp(b*x)
Coefficients (with 95% confidence bounds):
a = 0.8936 (0.7967, 0.9905)
b = -1.429 (-1.898, -0.96)
plot(time_1,conc_1,'ro')
hold on
plot(mdl)
So a simple negative exponential fits poorly.
Can I get a good fit? Well, using my SLM toolbox (which will need the optimization toolbox.)
slm = slmengine(time_1,conc_1,'decreas','on','plot','on','knots',[-.02 .5 1 2 4 6 10],'concaveup','on','minvalue',0);
But you won't have a function that you can write down, just a spline fit. It can be evaluated anywhere
Or, with some slightly more effort, you could try to build a nonlinear model. So, back to the curve fitting toolbox...
ft = fittype('a*exp(-b*(t + .02).^c)','independent','t','coef',{'a','b','c'})
ft =
General model:
ft(a,b,c,t) = a*exp(-b*(t + .02).^c)
mdl = fit(time_1',conc_1',ft,'startpoint',[1 -1 1])
mdl =
General model:
mdl(t) = a*exp(-b*(t + .02).^c)
Coefficients (with 95% confidence bounds):
a = 1.052 (1.013, 1.091)
b = 1.426 (1.352, 1.5)
c = 0.6074 (0.5562, 0.6587)
plot(time_1,conc_1,'bo')
hold on
plot(mdl)
grid on
The reason I added 0.02 there to t is to ensure that I did not raise negative numbers to a non-integer power.
This seems to be a reasonable model.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!