Clear Filters
Clear Filters

How to find the coordinates of contours when they go out of bounds and form multiple contours?

8 views (last 30 days)
I am trying to get the coordinates of the contour lines that go out of the bounds of plot resulting in division of line. As I am running multiple loops, I intend to keep the lines together or just join the two lines by adding points along the bounds of the plot. For example, it would be acceptable if the line shown in the plot below travels along horizontal axis from 12 to 54.
load('contours.mat')
pk = -32;
[c2] = contourf(x2,y2,z35b, [pk pk] ,'ShowText','on',FaceAlpha=0.2,EdgeAlpha=0.5,EdgeColor='#D95319'); axis equal
The problem is, when I retreive the coordinates stored in contour plot, first, it adds additional points (probably due to some additional peaks too small to be visible probably) which when joined gives random additional points (shown by blue lines below) which are not desirable for my code.
figure
[c2] = contourf(x2,y2,z35b, [pk pk] ,'ShowText','on',FaceAlpha=0.2,EdgeAlpha=0.5,EdgeColor='#D95319');
hold on
c2 = c2';
plot(c2(:,1),c2(:,2),'.:',MarkerEdgeColor='r')
axis equal
My failed approaches:
I tried to use approaches like using fit but it does not work (output shown below).
I also tried using sort but it also gives similar results.
I would like to find a solution where the best case scenario is tha that the lines travel along the contour and where it goes out of bounds, it just travels along the boundary until it meets the next line(as hand drawn for demonstration by yellow line in figure below). I shall be thankful for the help in achieving the desired results.

Accepted Answer

Star Strider
Star Strider on 12 Nov 2023
Edited: Star Strider on 13 Nov 2023
Here is my approach to this —
load('contours.mat')
pk = -32;
[c2] = contourf(x2,y2,z35b, [pk pk] ,'ShowText','on',FaceAlpha=0.2,EdgeAlpha=0.5,EdgeColor='#D95319');
axis equal
hold on
idx = find(c2(1,:) == pk);
for k = 1:numel(idx)
cl = c2(2,idx(k));
idxrng = idx(k)+1:idx(k)+cl;
x{k,:} = c2(1,idxrng);
y{k,:} = c2(2,idxrng);
cext(k,:) = [x{k}([1 end]) y{k}([1 end])]; % Ends Of Each Contour
cextm(:,:,k) = [cext(k,[1 2]); cext(k,[3 4])].'; % Consolicated Matrix
plot(x{k}, y{k}, '-r', 'LineWidth',2)
% plot(x{k}([1 end]), y{k}([1 end]), 'rs', 'MarkerFaceColor','r', 'DisplayName','Contour End Points')
% plot(x{k}([1 end]), y{k}([1 end]), 'r-', 'LineWidth',2.5, 'DisplayName','Line Joining Contour End Points')
end
mcextm = [cextm(:,:,1); cextm(:,:,2)]; % Concatenate Into One Matrix Of '(x,y)' Pairs In Each Row
dst = pdist([cextm(:,:,1); cextm(:,:,2)]); % Distance
sfdst = squareform(dst); % Distance Matrix
sfdst(sfdst==0) = Inf; % Zero Values On Diagonal = Inf
[r,c] = find(sfdst==min(dst)); % Minimum Row & Col
closest = mcextm([r(1) c(1)],:) % Match To 'mcextm' Rows
closest = 2×2
140.0000 24.5463 124.6852 -20.0000
% plot(closest(:,1), closest(:,2), '-r') % Check
plot(closest(1,1)*[1 1], closest(:,2), 'r', 'LineWidth',3)
plot(closest(:,1), closest(2,2)*[1 1], 'r', 'LineWidth',3)
This is definitely not robust to all such problems, however it can likely be modified for them.
The code first isolates the (x,y) coordinates of the contours, and their end-points. (That’s the easy part.) The challenging part is then defining the closest end points on the different sections of the same contour level (-32 here). The pdist function works for this, and using the squareform function results with find then permits relatively straightforward recognition of the coordinates of the closest points between the two different sections of the contour, returning the row and column indices of the closest ponts that are used to return the results in the ‘closest’ variable. The next problem is then plotting the line along the edge of the axes to join the nearest contour ends. I plotted them in red because it¹s easier to see them.
This is an interesting problem.
EDIT — (13 Nov 2023 at 05:31)
Slightly expanded the explanation of the closest points determination.
.
  6 Comments
UH
UH on 14 Nov 2023
Thank you very much for your interest. My data are like 16 gigs in total. I will tinker it to a manageable size and simplified problem description and send it to you, probably via message if you allow.
ps I just found out that the first column in contourf matrix is not the coordinate points. Probably that is why I was getting those points outside of the contours.
Star Strider
Star Strider on 14 Nov 2023
They are segmented (2xN) vectors. The first row of each segment has the level of each segment as its first element, and the corresponding index location in the second row is the number of elements (length) in that segment of the vector. My code searches for the level value in the first row, retrieves that position and value and the corresponding value in the second row and uses those to get the ‘x’ and ‘y’ vectors for that particular contour segment, using the ‘idxrng’ vector. It then stores them as cell array elements.

Sign in to comment.

More Answers (0)

Categories

Find more on Contour Plots in Help Center and File Exchange

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!