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

27 visualizaciones (últimos 30 días)
Sarah Armstrong
Sarah Armstrong el 25 de Sept. de 2019
Comentada: Sarah Armstrong el 30 de Sept. de 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 comentarios
dpb
dpb el 25 de Sept. de 2019
Make it easy for somebody to help you...attach the data points
Sarah Armstrong
Sarah Armstrong el 25 de Sept. de 2019
Of course! I have p_tn (x values) and p_Tn (y values) attached in a .mat file. Thanks!

Iniciar sesión para comentar.

Respuesta aceptada

darova
darova el 25 de Sept. de 2019
Look HERE and HERE
  6 comentarios
darova
darova el 26 de Sept. de 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 el 30 de Sept. de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Ted Shultz
Ted Shultz el 25 de Sept. de 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')

Categorías

Más información sobre Interpolation en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by