Fit a curve to data points x = f(y)

38 Ansichten (letzte 30 Tage)
Sarah Armstrong
Sarah Armstrong am 25 Sep. 2019
Kommentiert: Sarah Armstrong am 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 Kommentare
dpb
dpb am 25 Sep. 2019
Make it easy for somebody to help you...attach the data points
Sarah Armstrong
Sarah Armstrong am 25 Sep. 2019
Of course! I have p_tn (x values) and p_Tn (y values) attached in a .mat file. Thanks!

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

darova
darova am 25 Sep. 2019
Look HERE and HERE
  6 Kommentare
darova
darova am 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
Sarah Armstrong
Sarah Armstrong am 30 Sep. 2019
Awesome, I will play around with this instead of using a loop. I am also thinking about trying polar co-ordinates to see if that can refine it as well, but for now the curve is accurate enough as-is! Thank you for your help.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Ted Shultz
Ted Shultz am 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')

Kategorien

Mehr zu Interpolation finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by