How to filter out the noisy portion of contourf plot?
8 views (last 30 days)
Show older comments
The code below shows a ´contourf´ plot
load('impdta.mat')
[C,h] = contourf(x1,y1,ua, 'ShowText','on',FaceAlpha=0.3,EdgeAlpha=0.2,EdgeColor='k',LevelStep=10);
clabel(C,h,'FontSize',7,'Color',[0.6 0.6 0.6])
axis equal
In the above contour plot, the left side of the contour shows a smooth trend. I want to use this contour plot to interpolate to a value (say 60), which in current situation gives multiple 'lines' (marked in red). Is there a way the cluttered contours can be filtered out? An idea could be to use limits of x from zero to 600, but there are multiple plots in which this noncluttered area changes location and the limits cannot be simply applied. I would like to filter out the cluttered portion and left with the smooth contour lines only so that when I interpolate the value, only distinct contours can be extracted. I would appreciate if a solution can be attained.
hold on
contourf(x1,y1,ua, [60 60], 'ShowText','on',FaceAlpha=0,EdgeAlpha=0.5,EdgeColor='r');
0 Comments
Accepted Answer
Star Strider
on 20 Aug 2024
Edited: Star Strider
on 20 Aug 2024
By inspection, the longest part of the contour is likely the one you want to keep. It is relatively straightforward to find this because of the say the contour matrices are created. When I did thtat and plottted it, there was a gap on the left end that did not yield itself easily to any sort of analytic approach, so I just set up a find call with the appropriate conditions to retrieve those indices.
It may not be the most elegant approach, however it has the virtue of working.
Try this —
load('impdta.mat')
[C1,h1] = contourf(x1,y1,ua, 'ShowText','on',FaceAlpha=0.3,EdgeAlpha=0.2,EdgeColor='k',LevelStep=10);
clabel(C1,h1,'FontSize',7,'Color',[0.6 0.6 0.6])
axis equal
hold on
C2 = contour(x1,y1,ua, [60 60], 'ShowText','on',FaceAlpha=0,EdgeAlpha=0.5,EdgeColor='r', LineWidth=2);
idx1 = find(C2(1,:)==60); % Extact Longest Contour
Len1 = C2(2,idx1);
[maxLen1,lenidx1] = max(Len1);
xv1 = C2(1,idx1(lenidx1)+1:C2(2,idx1(lenidx1)));
yv1 = C2(2,idx1(lenidx1)+1:C2(2,idx1(lenidx1)));
idx2 = find(C2(1,:)<=min(xv1) & C2(2,:)>=max(yv1)); % Search For The Indices of the Rest Of It
xv2 = C2(1,idx2);
yv2 = C2(2,idx2);
figure
[C1,h1] = contourf(x1,y1,ua, 'ShowText','on',FaceAlpha=0.3,EdgeAlpha=0.2,EdgeColor='k',LevelStep=10);
clabel(C1,h1,'FontSize',7,'Color',[0.6 0.6 0.6])
axis equal
hold on
plot(xv1, yv1, '-r', LineWidth=2)
plot(xv2, yv2, '-r', LineWidth=2)
hold off
EDIT — (19 Aug 2024 at 14:44)
Plotting that contour on the surface —
whos('0file','impdta.mat')
Fua = scatteredInterpolant(x1(:), y1(:), ua(:));
xc = [xv1 xv2];
yc = [yv1 yv2];
zc = Fua(xc(:), yc(:));
figure
surfc(x1, y1, ua)
colormap(turbo)
hold on
plot3(xc, yc, zc+7, '-r', LineWidth=2)
hold off
I beleive this is what you want. If you want something else, please be specific.
.
8 Comments
More Answers (2)
John D'Errico
on 20 Aug 2024
Edited: John D'Errico
on 20 Aug 2024
One basic rule that always applies to things like this. You DON'T want to smooth contours after you have found them. You can't try to get rid of bumpy, messy contours. The result, even if you managed to do so, would be further artifacts. It is just a bad idea.
Instead, your goal should be to smooth the original data as a smooth, well-behaved surface. Only then do you want to generate the contours. The result will be far better behaved contours, and a better result.
So smooth your data, FIRST. There are many ways you can achieve that goal. But before we even think about that, let me look at your data. ALWAYS PLOT ALL DATA. Plot everything.
load impdta.mat
surf(x1,y1,ua)
xlabel x1
ylabel y1
zlabel ua
In this case, of course, the data in one half of that surface is wildly more noisy than the data in the other half. Contours in the part where x is greater than around say 750 (column 20 was at x=750) are meaningless, and any amount of smoothing will probably not help. Your data is just random noise in that part, and contours would be meaningless there, even if you did smooth the data. As such, honestly I'd just truncate that half of your data for the purposes of making contours. If I take the first 20 columns of each array, we see some trash in one corner, but it is not too excessive.
surf(x1(:,1:20),y1(:,1:20),ua(:,1:20))
xlabel x1
ylabel y1
zlabel ua
I might be willing to smooth that half, and only then compute the contours. It also looks like you have some missing data along two edges.
Now, re-reading your question, I see you have decided that a simple limit applied on x will not work. Such is life. The complex solution you hope exists, and want to magically work will not work, so you are going to need to do something that is possible to do, even if it is not as easy as you wish.
I might suggest looking at the local noise in your surface. In any region where the noise is too high, above some tolerance, I would just delete all data in that area. That is, replace it with a NaNs before you compute the contours. How can you compute the local noise? One approach might be to look at the local residual variance, AFTER you subtract off a locally planar fit. So at any node in the array, take the 8 nearest neighbors, and fit a plane through them. There will be problems around the edges of course, and you don't show much data.
2 Comments
Image Analyst
on 20 Aug 2024
I agree with you but I'm wondering two things.
- The main problem, as he sees it, is that some contour lines (like for 60) are apparently "broken" (have gaps in them). Why is that? Is it merely a problem of the surface contour becoming so steep there that multiple contours overlap there and only one can be displayed? Or is it a problem of just not showing it because of subsampling for display (like maybe enlarging the diagram might show them)?
- Why does muha want smoothing in the first place? Why would he want a less accurate, smoother contour plot? What's wrong with more accurate contours that follow the data?
Image Analyst
on 20 Aug 2024
So it sounds like you want to remove local outliers and noise but do not want to touch/smooth data points that you consider to be "good". So you want denoising. I have some ideas around that if you can consider your data as a grid so that we can treat it as an image. But I don't have time now. I'll give a longer, more thorough answer later today. Please be patient. In the meantime, see this excellent overview of image denoising methods by Prof. Milanfar.
1 Comment
Image Analyst
on 21 Aug 2024
From your reply to @Star Strider it appears you don't want to denoise your data, but just want the longest contour line, so I won't give anymore denoising information.
See Also
Categories
Find more on Convert Image Type 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!