Fit a curve to data points x = f(y)
47 views (last 30 days)
Show older comments
Sarah Armstrong
on 25 Sep 2019
Commented: Sarah Armstrong
on 30 Sep 2019
Hello,
I have data points represented by red stars on a graph (Fig 1, attached), and I would like to fit a curve to them. The curve does not have to be accurate -- it just needs to serve as a visual guide. I have drawn a sketch below to show what I would like. The other curves on the graph are by-products from the code I pulled this image from, and are not relevant to this problem. How can I fit a curve to the red data points in MATLAB?
--------------------
I have tried using polyfit, smoothingspline, pchip and other curve-fitting tools, but all of them connect the wrong data points together, since this graph is actually x = f(y). In MS Excel, if I switch the axes so the curve becomes a one-to-one function where y = f(x), I can easily fit a quadratic curve to the points.
I am currently plotting each point indivdually. I can plot the points with a line, but it is not very smooth (see Fig 2, attached). I guess I could just increase the number of data points, but that increases computation time too much. Any suggestions?
Please find below some things I have already tried. The red data points are saved in 1 x 11 doubles p_tn (x values) and p_Tn (y values).
Thank you so much! PLEASE let me know if you need more information, clarification, or data.
%Attempt 1 - Polyfit
[p,s,mu] = polyfit(p_Tn,p_tn,3);
[Y,delta] = polyval(p,p_Tn,s,mu)
X = linspace(0,0.05,length(Y));
plot(Y,X,'k-')
%Attempt 2 - Non parametric fitting
xq = linspace(0,0.05,100);
p = pchip(p_tn',p_Tn',xq);
pp = ppval(p,xq);
plot(xq,pp);
%Attempt 3 - Smoothingspline
f = fit(p_tn',p_Tn','smoothingspline');
plot(f)
%Attempt 4 - Split upper and lower half of data points and use polyfit
for i = 1:length(p_tn)-1
if p_tn(i) > p_tn(i+1)
x1(i) = p_tn(i) ;
y1(i) = p_Tn(i) ;
elseif p_tn(i) < p_tn(i+1)
x2(i) = p_tn(i) ;
y2(i) = p_Tn(i) ;
end
end
p1 = polyfit(x1,y1,2);
p2 = polyfit(x2,y2,2);
xf1 = linspace(min(x1),0.05);
xf2 = linspace(min(x2),0.05);
f1 = polyval(p1,xf1);
f2 = polyval(p2,xf2);
plot(x1,y1,x2,y2)
plot(xf1,f1,'r--')
plot(xf2,f2,'r')
2 Comments
Accepted Answer
darova
on 25 Sep 2019
6 Comments
darova
on 26 Sep 2019
DOn't know why you need loop? I believe separating data into groups should work!
Or maybe interpolate all data with spline and interp1 and fill with NaN areas you don't want
ind = y(3) < y1 & y1 < y(end-1); % indices between ends
Experiment to get the result you want
More Answers (1)
Ted Shultz
on 25 Sep 2019
Because you are looking to make a function of “y” rather than “x”, you would need to flip the X and Y when you solve the equation (this is equivalent to when you rotated in excel).
Try something like this:
p = polyfit(y,x,n)
y1 = linspace(0,4*pi);
x1 = polyval(p,y1);
figure
plot(x,y,'o')
0 Comments
See Also
Categories
Find more on Interpolation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!