Extract data from curve fit toolbox - matlab

I am using matlab and I have a certain set of x and y data,
x=[0,1.25,1.88,2.5,5,6.25,6.88,7.19,7.5,10,12.5,15,20];
y=[-85.93,-78.82,-56.95,-34.56,-33.57,-39.64,-41.96,-49.28,-66.6,-66.61,-59.16,-48.78,-41.53];
I want to use the curve fitting toolbox which has the spline function to generate a graph, so i did this,
cftool
It would bring me to the toolbox which i can then choose the spline fit. I was thinking if its possible that i extract the data points from the spline graph generated. Which means i probably would have more x and y data points than those that i input in, since the spline graph is sort of a continuous graph. Anyone could give me some advice on this? Thanks!

You can perform the equivalent of the spline fit performed with cftool with fit, see for instance here, here, or here:
% perform spline fit without cftool
ft = fittype('cubicspline');
coeff=fit(x,y,ft);
% use plot to display the interpolating polynomial
% (relying on internal plot settings)
figure
h=plot(coeff,x,y,'o');
% extract the *interpolated* curve from the figure
xi=get(h,'XData');
yi=get(h,'YData');
Replot it just to show that we can:
But if you just want to interpolate do as Fraukje explained here. Define a finer grid on x and use the interp1 function, as in the following example (same x,y input data as before):
% interpolate
Ni = 100;
xi = linspace(x(1),x(end),Ni);
yi = interp1(x,y,xi,'spline');
Now xi,yi is the interpolated data:

Related

How to create a curve that will best fit the points in my plot

lmd = 10;
k = poissrnd(lmd,1,100000);
q = exp(-lmd).*((lmd.^k)./factorial(k));
plot(k,q,'.')
I cant connect my points through plot() since it comes out a jumbled mess. How can I plot a curve of the points I have that will best fit the data.
Use curve fitting toolbox of the MATLAB and it provides you with so many fitting options. You can find which option works best for you by try and error.
If you want to use spline, use yy=spline(x,y,xx) command. Then use plot(xx,yy) to plot the curve.
Sort the data
[x,i] = sort(k);
y = q(i);
plot(x,y);
If you have to "fit" the data, try cubic spline interpolation.

Remove base line drift with peicewise cubic spline algorithm using MATLAB

I have a signal which I want to remove the basline drift using the picewise cubic spline algorithm in MATLAB.
d=load(file, '-mat');
t=1:length(a);
xq1=1:0.01:length(a);
p = pchip(t,a,xq1);
s = spline(t,a,xq1);
%
figure, hold on, plot(a, 'g'), plot(t,a,'o',xq1,p,'-',xq1,s,'-.')
legend('Sample Points','pchip','spline','Location','SouthEast')
But I cant see any basline removal..The orginal data is exactly on the interpolated one.
or in the other signal as we can see no base line is removed.
The question is how I can "use peicewise cubic spline interpolation to
remove basline drift" in MATLAB.
Thank you
It seems likely that you are looking to fit a polynomial to your data to estimate baseline drift due to thermal variations. The problem with spline is that it will always perfectly fit your data (similar to pchip) because it is an interpolation technique. You probably want a courser fit which you can get using polyfit. The following code sample shows how you could use polyfit to estimate the drift. In this case I fit a 3rd-order polynomial.
% generate some fake data
t = 0:60;
trend = 0.003*t.^2;
x = trend + sin(0.1*2*pi*t) + randn(1,numel(t))*0.5;
% estimate trend using polyfit
p_est = polyfit(t,x,3);
trend_est = polyval(p_est,t);
% plot results
plot(t,x,t,trend,t,trend_est,t,x-trend_est);
legend('data','trend','estimated trend','trend removed','Location','NorthWest');
Update
If you have the curve fitting toolbox you can fit a cubic spline with an extra smoothing constraint. In the example above you could use
trend_est = fnval(csaps(t,x,0.01),t);
instead of polyfit and polyval. You will have to play with the smoothing parameter, 0 being completely linear and 1 giving the same results as spline.
I think you should reduce the number of points at which you calculate the spline fit (this avoids over-fitting) and successively interpolate the fit on the original x-data.
t = 0:60;
trend = 0.003*t.^2;
x = trend + sin(0.1*2*pi*t) + randn(1,numel(t))*0.5;
figure;hold on
plot(t,x,'.-')
%coarser x-data
t2=[1:10:max(t) t(end)]; %%quick and dirty. You probably wanna do better than this
%spline fit here
p = pchip(t,x,t2);
s = spline(t,x,t2);
plot(t2,s,'-.','color' ,'g')
%interpolate back
trend=interp1(t2,s,t);
%remove the trend
plot(t,x-trend,'-.','color' ,'c')

How to extract residuals from curvefit

I'm using curve fit in Matlab R2016a to find the best fit between two arrays. One array represents a certain value at a given latitude and longitude and the other array represents the date that value was collected.
In using the curve fit tool I'm able to find a line of best fit as well as to plot the residuals. The residuals are all I care about-- however, when I export the residuals to the workspace they are represented as one column of numbers. This isn't helpful to me without the identifying information of that residual's relationship to the original arrays (i.e., which X,Y pair does each residual correspond to?)
The data from the residuals graph in the curve fit tool is exactly what I want. Is there a way to export this in a manner that makes it usable?
The cftool uses fit at its heart. What you can do to further explore the fit and its residuals is export the fit to your workspace. Do this through the 'Fit' menu at the top of the Curve Fitting Tool window, then select 'Save to Workspace'. Using this fit object (a cfit for a curve or an sfit for a surface), you can do the same analyses and more as with the curve fitting tool.
Let me illustrate how to obtain a fit, create a plot of the residuals and how to calculate the residuals. The resulting image is shown below. In the code, the residuals variable contains the residuals of the fit with each element belonging to each sample pair in x and y.
% Generate data
rng default
x = sort(rand(10, 1));
y = randn(size(x)) - 3*x;
% Fit a line
fitted = fit(x, y, fittype('poly1'));
% Plot fitted line with data
figure
subplot 311
plot(fitted, x, y)
% Plot residuals
subplot 312
plot(fitted, x, y, 'residuals)')
ylabel residuals
% Get residuals
residuals = y - fitted(x);
% Create stem plot of residuals
subplot 313
stem(x, residuals)
legend residuals
xlabel x
ylabel residuals

How to export fitted curve to 1D vector

With the use of Curve Fitting toolbox I'm fitting to 11 data points a curve described by a custom equation. As a result I get something like this:
I want to save 1D vector represented bye the red line on the plot above into a matlab variable. I try to use Fit->Save to Workspace... option from the Curve Fitting toolbox menu, but saved variables do not contain any of the fitted data.
How can I save fitted data into matlab variable?
The saved MATLAB-object (default name is fittedmodel) contains the fitted function as a function-handle and the fitted coefficients corresponding to this function-handle. You can then evaluate at the data points of your choice with feval.
In the following example the fitted function will be evaluated at the original datapoints x:
y = feval(fittedmodel, x);
Now you can directly plot the result:
plot(x,y);

matlab: cdfplot of relative error

The figure shown above is the plot of cumulative distribution function (cdf) plot for relative error (attached together the code used to generate the plot). The relative error is defined as abs(measured-predicted)/(measured). May I know the possible error/interpretation as the plot is supposed to be a smooth curve.
X = load('measured.txt');
Xhat = load('predicted.txt');
idx = find(X>0);
x = X(idx);
xhat = Xhat(idx);
relativeError = abs(x-xhat)./(x);
cdfplot(relativeError);
The input data file is a 4x4 matrix with zeros on the diagonal and some unmeasured entries (represent with 0). Appreciate for your kind help. Thanks!
The plot should be a discontinuous one because you are using discrete data. You are not plotting an analytic function which has an explicit (or implicit) function that maps, say, x to y. Instead, all you have is at most 16 points that relates x and y.
The CDF only "grows" when new samples are counted; otherwise its value remains steady, just because there isn't any satisfying sample that could increase the "frequency".
You can check the example in Mathworks' `cdfplot1 documentation to understand the concept of "empirical cdf". Again, only when you observe a sample can you increase the cdf.
If you really want to "get" a smooth curve, either 1) add more points so that the discontinuous line looks smoother, or 2) find any statistical model of whatever you are working on, and plot the analytic function instead.