Plotting a faired curve through a data set that curves in on itself
2 views (last 30 days)
Show older comments
I am trying to plot a curve that goes through all the points in my data set using a fit method. I have tried using interp1 with smoothing spline and makima, I have tried fit, and I have tried polyfit. In all cases it does not work. My data set is values of CM (pitching moment) vs CL (lift coefficient). The first 11 of my 14 data points are increasing CL and decreasing CM, but then from the 12th to 14th data points, my values of CL decrease whilst the values of CM also decrease (due to stall). In this way, the curve goes in on itself. My question is, is there a way to plot a single curve that goes through (or at least mostly) goes through all of the points even though CL is not strictly increasing over the entire interval?
Here is what the raw data looks like:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1667926/image.png)
Any help would be greatly appreciated. Many thanks in advance.
7 Comments
John D'Errico
on 13 Apr 2024
Edited: John D'Errico
on 13 Apr 2024
As you have been told, you CANNOT model this as a function. You CANNOT use interp1 as you are trying to do, or to use fit directly. In all those cases, trying to model C_M as a function of C_L would result in something that is not a single valued function. That is, for C_L == 1.3, exactly which single choice for C_M should the model return? That is what a single valued function would do. And that is why your attempts with a spline, with a polynomial, with interp1, etc. all failed. Any such tool MUST presume a single valued function. For any give value of x, there would be EXACTLY one y.
What can you do? You can use tools like cscvn. It allows a non-single valued function. Curves by that tool can follow any set of points you give it. The result will NOT be a simple function you can evaluate however, because again, if you want to evaluate a function, it must be single valued!
The other choice is to swap x and y, as has been suggested. In this case, swapping the relationship results in a single valued function that can be fit. (That need not always be the case. for example with points around a circle.) Once you do that on your data however, the result is a single valued relationship, x(y). Here that would be C_L(C_M). But it cannot predict in the other direction. How could it do that? If all you want to do is plot a curve from that data, you could do this:
CL = [-0.117323468280501
0.109533077818298
0.349535877911274
0.578159011570390
0.799525368741050
0.989291914638142
1.15205588979230
1.23246920496028
1.29909262861280
1.35437407382001
1.35912940969856
1.34136836172825
1.29541307340786
1.11501423385178];
CM = [0.150258158337099
0.117407098855973
0.0884047743485015
0.0670114607977137
0.0517955492445810
0.0305383477518936
0.00355285590629767
-0.00978950167650419
-0.0257317663408145
-0.0378647559486718
-0.0873543217991825
-0.0904845481307666
-0.103361954196992
-0.184021637962439];
spl = cscvn([CL,CM]')
fnplt(spl)
hold on
plot(CL,CM,'ro')
xlabel 'C_L'
ylabel 'C_M'
hold off
It is a little bumpy on the right, but that is due to it trying to interpolate those points exactly. It needed to make some sharp turns. The curve generated by @Voss using a smoothing spline is nicer (smoother) looking, but it does not interpolate the data. You could also do this, as a pure interpolant:
spl2 = spline(CM,CL);
plot(CL,CM,'ro')
CMint = linspace(min(CM),max(CM));
hold on
plot(fnval(spl2,CMint),CMint,'-b')
xlabel 'C_L'
ylabel 'C_M'
hold off
So you need to make a choice. If all you want to do here is plot a smooth curve through the data, then there are at least a few options, depending on how smooth of a curve you want. Do you want a curve that follows the data exactly? Thus, an interpolant? Do you want a smoother curve, that comes close to the data?
Answers (1)
Mathieu NOE
on 16 Apr 2024
Edited: Mathieu NOE
on 16 Apr 2024
hello
experimental airfoil data can exibit some randomness especially at high angle of attack (stall)
we usually prefer to smooth the data rather to go exactly through the points (IMHO)
so a very simple code that interpolates and smooth the data :
CL = [-0.117323468280501
0.109533077818298
0.349535877911274
0.578159011570390
0.799525368741050
0.989291914638142
1.15205588979230
1.23246920496028
1.29909262861280
1.35437407382001
1.35912940969856
1.34136836172825
1.29541307340786
1.11501423385178];
CM = [0.150258158337099
0.117407098855973
0.0884047743485015
0.0670114607977137
0.0517955492445810
0.0305383477518936
0.00355285590629767
-0.00978950167650419
-0.0257317663408145
-0.0378647559486718
-0.0873543217991825
-0.0904845481307666
-0.103361954196992
-0.184021637962439];
% interpolate
CM2 = linspace(min(CM),max(CM),100);
CL2 = interp1(CM,CL,CM2,'linear');
% smooth
N = 20;
CL2s = smoothdata(CL2,'lowess',N);
plot(CL,CM,'*-');
hold on
plot(CL2s,CM2,'-');
xlabel 'C_L'
ylabel 'C_M'
hold off
1 Comment
Mathieu NOE
on 28 May 2024
hello again
problem solved ?
please accept the answer that best matches your expectations - it rewards people who have worked on your problem
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!