How to find the coordinates of contours when they go out of bounds and form multiple contours?
8 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
UH
el 12 de Nov. de 2023
Comentada: Star Strider
el 14 de Nov. de 2023
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.
0 comentarios
Respuesta aceptada
Star Strider
el 12 de Nov. de 2023
Editada: Star Strider
el 13 de Nov. de 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
% 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 comentarios
Star Strider
el 14 de Nov. de 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.
Más respuestas (0)
Ver también
Categorías
Más información sobre Contour Plots en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!