Find best fit curve from multiple curves of different size
Show older comments
Hi,
I have multiple curves with different lengths. When plotted they look like the image below. I want to find one best fit line that best describes all the curves. The best fit line should look something like the second image below. The data is attached. From the data Z is on the x axis, R is on the y axis.


Accepted Answer
More Answers (1)
John D'Errico
on 26 Feb 2025
Edited: John D'Errico
on 26 Feb 2025
On the right end, you have an infinite slope. On the left end, not so much of a problem. But it will be better to do a couple of things. First, these look almost like arcs of an ellipse. So lets pretend they are that, or at least something close.
What you need to understand is an ellipse is just a circle that has been stretched. So we can undo that.
First, I'll rescale the axes.
load Z.mat
load R.mat
whos
I'll set the center of the coordinate system at (Z,R) = (30,-15), and then rescale R and Z, so they will now be roughly circular. Then I could transform to polar coordinates. At least, if I needed to do so. But do I?
R0 = -15;
Z0 = 30;
Rtrans = @(r) (r - R0)/(max(r) - R0);
Ztrans = @(z) (z - Z0)/(max(z) - Z0);
for i = 1:9
plot(Ztrans(Z{i}),Rtrans(R{i}))
hold on
end
axis equal
xlim([0 1])
ylim([0,1])
hold off
grid on
Not too bad. Do you see that by simply rescaling the axes by the endpoints of the curves, we now have all the curves virtually on top of each other?
My gut tells me that this may be sufficient for your purposes. Essentially, all you need to know are those endpoints, and you can reconstruct any curve, from this almost circular common arc.
Now, how, you might ask, can you use that curve, as a common arc, and to then reconstruct the original curves from it? Simpler (maybe) than you think.
Rmax = cellfun(@max,R)
Zmax = cellfun(@max,Z)
Next, once all of the curves are in this globally consistent form, convert to polar and model rhe result.
Rcommon = [];
Zcommon = [];
for i = 1:9
Rcommon = [Rcommon;Rtrans(R{i})];
Zcommon = [Zcommon;Ztrans(Z{i})];
end
[thet,rad] = cart2pol(Zcommon,Rcommon);
plot(thet,rad,'.')
There we see that one of your curves is a little unlike the others. But the difference is not too immense, if you look at the scale on the y-axis in that last plot.
mdl = fit(thet,rad,'poly4')
plot(mdl,thet,rad)
If you look carefully, the blue curve falls neatly in the middle of that band. Now, we can reconstruct each of the curves, as well as plot a common curve on top, with an average set of parameters.
The model is a function of polar angle theta, varying from 0 to pi/2 radians. So the global curve will be:
thetglob = linspace(0,pi/2,20)';
radglob = mdl(thetglob);
[Zglob,Rglob] = pol2cart(thetglob,radglob);
Zmaxbar = mean(Zmax);
Rmaxbar = mean(Rmax);
plot(Zglob*(Zmaxbar - Z0)+ Z0,Rglob*(Rmaxbar - R0) + R0)
I've used average values to undo the transformations.
Categories
Find more on Axis Labels in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




