Azzera filtri
Azzera filtri

How to filter out the noisy portion of contourf plot?

46 visualizzazioni (ultimi 30 giorni)
Muha
Muha il 20 Ago 2024 alle 12:14
Commentato: Star Strider il 22 Ago 2024 alle 11:26
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');

Risposta accettata

Star Strider
Star Strider il 20 Ago 2024 alle 12:55
Modificato: Star Strider il 20 Ago 2024 alle 14:44
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.
.
  4 Commenti
Muha
Muha il 22 Ago 2024 alle 11:18
I have worked on the other solutions discussed. One thing that worked was that I simply put limits from -100 to 100. It is simple solution so far and works reasonably
[c12,h12] = contourf(x1,y1,ua,[-100:10:100], 'ShowText','on',FaceAlpha=0.6,EdgeAlpha=0.5,EdgeColor='k',LevelStep=10);
This step when added on your idea works as I have thought it should. There is a bit more tinkering I am working which I think will be managed as it develops.
Thank you for all the guidance.

Accedi per commentare.

Più risposte (2)

John D'Errico
John D'Errico il 20 Ago 2024 alle 12:31
Modificato: John D'Errico il 20 Ago 2024 alle 13:10
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 Commenti
Image Analyst
Image Analyst il 20 Ago 2024 alle 12:47
I agree with you but I'm wondering two things.
  1. 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)?
  2. 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?
Muha
Muha il 20 Ago 2024 alle 13:22
Dear @John D'Errico thank you for your detailed analysis on the problem. These data are gathered experimentally as a grid was plotted and the response was collected from each node in the grid. It can be analogous to a situation where as the signal becomes weak, the noise becomes more. As it is experimental data, no smoothing has been or can be carried out. And, currently, the signal strength cannot be characterized so that we can simply discard the low strength data. I do not intend to smooth the data. However, I just want to discard the noisy data. As you have suggested, I will use the approach you have advised using local residual variance. I will get back to you if there is any success.
@Image Analyst there was no resampling carried out. These data are collected as a difference in signal arrival. In some cases the signals were distinct and clear, in others there could have been errors. I have explained in response to @John D'Errico why the noise is there. I would not go for smoothing. Probably I phrased it in a way that it sounded like that. I intend to keep the smooth lines contour only and discard the jaggedy contours. Their suggestiuon of approaching using the residual variance sounds like a good approach which I am looking into right now.
Again, thank you, these comments gave me some idea to proceed further. Cheers. I will get back in case of success.

Accedi per commentare.


Image Analyst
Image Analyst il 20 Ago 2024 alle 15:08
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 Commento
Image Analyst
Image Analyst il 21 Ago 2024 alle 2:13
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.

Accedi per commentare.

Prodotti


Release

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by