Draw lines around specific regions in imagesc plot

조회 수: 17 (최근 30일)
Benjy Barnett
Benjy Barnett 2021년 3월 11일
편집: Elizabeth 2025년 4월 28일
I have a NxN matrix T that I am plotting with imagesc. This matrix is a matrix of t values. I would like to mark the t values that are significant. Ideally, I would draw around them with a black line in the imagesc plot. I have another NxN matrix of p values P.
So essentially, I want to find every element in P that is less than 0.05, and draw a line around the corresponding point in the imagesc representation of T. Also, if there are multiple elements next to eachtoehr that are below 0.05 in P, the line should ideally encompass all these points in one, rather than each element being encircled on its own.
Like how the top image looks in the attached image.
Thanks
  댓글 수: 1
Aleksandar Besevic
Aleksandar Besevic 2022년 12월 21일
Hey, did you ever manage to solve this? Having a similar issue whereby I want to draw a box/rectangle around a defect in an imagesc plot . Contour plot just creates a squiggle inside the pixel which is pretty useless

댓글을 달려면 로그인하십시오.

답변 (2개)

Image Analyst
Image Analyst 2022년 12월 21일

Elizabeth
Elizabeth 2025년 4월 27일
편집: Elizabeth 2025년 4월 28일
I had the exact same question for a time frequency plot, and couldn't find a function, so I ended up writing one. It was more complicated than I expected!
It takes a matrix in which members of the cluster are non-zero and everything else is zero. It outputs an N x 3 matrix of vertices, where N is the total number of "corners" of the patch. The vertices are ordered starting at one vertex and going round the edge of the cluster clockwise until you get back to where you started. The first and second columns are the X and Y coordinates of each vertex, respectively. The third column is the "perimeter number", as if there are any "holes" in the cluster, e.g. a clump of non-significant values enclosed by the cluster, you will need a separate array of ordered perimeter vertices representing the perimeter of the hole. When you draw each perimeter, you have to draw each separately, as you don't want a line connecting the edge of the cluster with the edge of the hole.
Then I used patch.m to overlay the perimeters on the time frequency plot.
Here's the function. Someone else might have done a simpler one by now, but this one worked for me!
function [ClusterVertices] = ClusterBorder(ClusterMap)
% CLUSTERBORDER function to draw line round a cluster of significant TFS
% cells in colourmap e.g. using imagesc.
%
% Takes a logical matrix showing a cluster of contiguous TFS cells, and
% and finds the coordinates of the internal and external vertices of the
% cluster, and orders them clockwise round the perimeter. The output of
% ordered vertices can be used with patch.m to draw a line round the cluster
%% Pads the cluster array with zeros by one cell all round
Mask=abs(ClusterMap)>0;
PaddedMask=padarray(1*Mask,[1,1],0);
%% Finds linear and subscript indices of all cluster cells
LinIdx=find(PaddedMask==1);
[Row,Col]=ind2sub(size(PaddedMask),LinIdx);
ClusterSubs=[Row,Col];
%% Find neighbours of each cell in mask
NCellIdx=sub2ind(size(PaddedMask),Row-1,Col);
SCellIdx=sub2ind(size(PaddedMask),Row+1,Col);
WCellIdx=sub2ind(size(PaddedMask),Row,Col-1);
ECellIdx=sub2ind(size(PaddedMask),Row,Col+1);
NWCellIdx=sub2ind(size(PaddedMask),Row-1,Col-1);
NECellIdx=sub2ind(size(PaddedMask),Row-1,Col+1);
SWCellIdx=sub2ind(size(PaddedMask),Row+1,Col-1);
SECellIdx=sub2ind(size(PaddedMask),Row+1,Col+1);
ClusterCellNeighbours=[...
PaddedMask(NWCellIdx),...
PaddedMask(NCellIdx),...
PaddedMask(NECellIdx),...
PaddedMask(ECellIdx),...
PaddedMask(SECellIdx),...
PaddedMask(SCellIdx),...
PaddedMask(SWCellIdx),...
PaddedMask(WCellIdx)];
%% Find Edge cells
EdgeCellIdx=sum(ClusterCellNeighbours,2)<8; % Find all edge cells
EdgeSubs=ClusterSubs(EdgeCellIdx,:);
EdgeCellNeighbours=ClusterCellNeighbours(EdgeCellIdx,:);
ExtTL_Subs=EdgeSubs(sum(EdgeCellNeighbours(:,[2,8]),2)==0,:);
ExtTR_Subs=EdgeSubs(sum(EdgeCellNeighbours(:,[2,4]),2)==0,:);
ExtBL_Subs=EdgeSubs(sum(EdgeCellNeighbours(:,[6,8]),2)==0,:);
ExtBR_Subs=EdgeSubs(sum(EdgeCellNeighbours(:,[4,6]),2)==0,:);
IntTL_Subs=EdgeSubs(ismember(EdgeCellNeighbours(:,[8,1,2]), [1,0,1], 'rows'),:);
IntTR_Subs=EdgeSubs(ismember(EdgeCellNeighbours(:,2:4), [1,0,1], 'rows'),:);
IntBL_Subs=EdgeSubs(ismember(EdgeCellNeighbours(:,6:8), [1,0,1], 'rows'),:);
IntBR_Subs=EdgeSubs(ismember(EdgeCellNeighbours(:,4:6), [1,0,1], 'rows'),:);
%% Finds coordinates of all cluster corners
ExtTL_verts=[ExtTL_Subs(:,2)-0.5,ExtTL_Subs(:,1)-0.5];
ExtTR_verts=[ExtTR_Subs(:,2)+0.5,ExtTR_Subs(:,1)-0.5];
ExtBL_verts=[ExtBL_Subs(:,2)-0.5,ExtBL_Subs(:,1)+0.5];
ExtBR_verts=[ExtBR_Subs(:,2)+0.5,ExtBR_Subs(:,1)+0.5];
IntTL_verts=[IntTL_Subs(:,2)-0.5,IntTL_Subs(:,1)-0.5];
IntTR_verts=[IntTR_Subs(:,2)+0.5,IntTR_Subs(:,1)-0.5];
IntBL_verts=[IntBL_Subs(:,2)-0.5,IntBL_Subs(:,1)+0.5];
IntBR_verts=[IntBR_Subs(:,2)+0.5,IntBR_Subs(:,1)+0.5];
%% Makes column indicating of direction of next vertex (in polar coords)
ExtTLlabel=repmat(0,size(ExtTL_verts,1),1);
ExtTRlabel=repmat(-pi/2,size(ExtTR_verts,1),1);
ExtBLlabel=repmat(pi/2,size(ExtBL_verts,1),1);
ExtBRlabel=repmat(pi,size(ExtBR_verts,1),1);
IntTLlabel=repmat(pi/2,size(IntTL_verts,1),1);
IntTRlabel=repmat(0,size(IntTR_verts,1),1);
IntBLlabel=repmat(pi,size(IntBL_verts,1),1);
IntBRlabel=repmat(-pi/2,size(IntBR_verts,1),1);
Vertices_Cat=[...
ExtTL_verts;...
ExtTR_verts;...
ExtBL_verts;...
ExtBR_verts;...
IntTL_verts;...
IntTR_verts;...
IntBL_verts;...
IntBR_verts];
Directions_Cat=[...
ExtTLlabel;...
ExtTRlabel;...
ExtBLlabel;...
ExtBRlabel;...
IntTLlabel;...
IntTRlabel;...
IntBLlabel;...
IntBRlabel];
Vertices_Cat=[Vertices_Cat,Directions_Cat];
%% Order Vertices clockwise round perimeter of cluster
Nvertices=size(Vertices_Cat,1);
ThisVertex=Vertices_Cat(1,:);
Vertices_Cat(1,:)=[NaN,NaN,NaN];
StartVertex=ThisVertex;
PerimeterID=1;
iVertex=1;
ClusterVertices=NaN(Nvertices,3);
ClusterVertices(1,1:2)=ThisVertex(1:2);
ClusterVertices(iVertex,3)=PerimeterID;
for iVertex=2:Nvertices
switch ThisVertex(3)
case 0 % Go right
NextIdx=find(Vertices_Cat(:,2)==ThisVertex(2));
Possibles=Vertices_Cat(NextIdx,:);
if StartVertex(2)==ThisVertex(2)
Possibles=[StartVertex;Possibles];
end
Possibles=Possibles(Possibles(:,1)>ThisVertex(1),:);
NextVertex=Possibles(Possibles(:,1)==min(Possibles(:,1)),:);
NextVertex=NextVertex(1,:); % to handle cases where the same vertex occurs twice
case pi % Go left
NextIdx=find(Vertices_Cat(:,2)==ThisVertex(2));
Possibles=Vertices_Cat(NextIdx,:);
if StartVertex(2)==ThisVertex(2)
Possibles=[StartVertex;Possibles];
end
Possibles=Possibles(Possibles(:,1)<ThisVertex(1),:);
NextVertex=Possibles(Possibles(:,1)==max(Possibles(:,1)),:);
NextVertex=NextVertex(1,:);
case pi/2 % Go up
NextIdx=find(Vertices_Cat(:,1)==ThisVertex(1));
Possibles=Vertices_Cat(NextIdx,:);
if StartVertex(1)==ThisVertex(1)
Possibles=[StartVertex;Possibles];
end
Possibles=Possibles(Possibles(:,2)<ThisVertex(2),:);
NextVertex=Possibles(Possibles(:,2)==max(Possibles(:,2)),:);
NextVertex=NextVertex(1,:);
case -pi/2 % Go down
NextIdx=find(Vertices_Cat(:,1)==ThisVertex(1));
Possibles=Vertices_Cat(NextIdx,:);
if StartVertex(1)==ThisVertex(1)
Possibles=[StartVertex;Possibles];
end
Possibles=Possibles(Possibles(:,2)>ThisVertex(2),:);
NextVertex=Possibles(Possibles(:,2)==min(Possibles(:,2)),:);
NextVertex=NextVertex(1,:);
end
if ~ismember(NextVertex,StartVertex,"rows")
ThisVertex=NextVertex;
else
PerimeterID=PerimeterID+1;
VerticesLeftIdx=find(~isnan(Vertices_Cat(:,1)));
ThisVertex=Vertices_Cat(VerticesLeftIdx(1),:);
StartVertex=ThisVertex;
end
[~,idx]=ismember(ThisVertex,Vertices_Cat,'rows');
Vertices_Cat(idx,:)=[NaN,NaN,NaN];
ClusterVertices(iVertex,1:2)=ThisVertex(1:2);
ClusterVertices(iVertex,3)=PerimeterID;
end
%% Remove padding from vertex coordinates
ClusterVertices(:,1:2)=ClusterVertices(:,1:2)-1;
end
Then I used the ClusterVertices matrix with patch.m:
Perimeters=ClusterVertices(:,3);
Nperimeters=max(Perimeters);
for iPerimeter=1:Nperimeters()
patch('Faces',1:sum(Perimeters==iPerimeter),'Vertices',...
ClusterVertices(Perimeters==iPerimeter,1:2),...
'FaceColor','none', 'EdgeColor','k','LineWidth',1)
end

카테고리

Help CenterFile Exchange에서 Vector Fields에 대해 자세히 알아보기

제품


릴리스

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by