I need to label edges of a directed graph with 4 different labels, so I store it in a N*N*4 array. (Let's stick with 4, which is my actual third dimension.) N is the number of nodes in the graph. i.e. for entry M(i,j,1), I would label an edge from node i to node j with the first kind of label. Here is a toy example to play with.
M(2,1,1)=1
indicates I add label text 'first label' on the edge from node 2 to node 1. M(3,2,2)=1
indicates I add label text 'second label' on the edge from node 3 to node 2. Each 'page' in the 3D array is one kind of label.
M(:,:,1)= 0 0 0 M(:,:,2)= 0 0 1
1 0 1 0 0 0
0 0 0 0 1 0
But I don't know how to convert N*N*4 array M
into s
and t
in labeledge(h,s,t,Labels)
. s
is the indices of source nodes while t
is the indices of target nodes.
Ideally, this is the plot:
s = [2 2 1 3];
t = [1 3 3 2];
G = digraph(s,t);
figure;
h = plot(G);
the key question is how I can get s1, t1, s2 and t2 from M like this:
labeledge(h,[2 2], [1 3], 'first label');
labeledge(h,[1 3], [3 2], 'second label');
FYI: M(:,:,1)
and M(:,:,2)
do not have the same non-zero entries.
Some Background Insight:
In your problem, the order of s
and t
is inter-linked i.e. shuffling of s
does not matter if the elements of t
are also shuffled in the same order. e.g; if
s = [2 2 1 3];
t = [1 3 3 2];
%The combination of s and t given by you
The above will give the same result as that of the following:
s = [2 3 2 1];
t = [1 2 3 3];
% replaced column 2 with column 3, column 3 with column 2, and column 4 with column 3
There are many such combinations.
The code I am going to show will give the following combination for the given M
:
s = [2 2 3 1]; %named as snew in my code
t = [1 3 2 3]; %named as tnew in my code
%In this combination, column 3 and 4 are inter-changed (See the combination given by you)
Code:
for k=1:size(M,3) %Looping depending on the third dimension
[r,c]= find(M(:,:,k)); %Finding non-zero elements
%Storing the values in a cell since the number of non-zero elements in each
%slice of M can be different
s{k}=r; t{k}=c;
end
The above code gives s{1}=[2; 2]
, s{2}=[3; 1]
, t{1}=[1; 3]
and t{2}=[2; 3]
.
Now you can find s
and t
as combined as given in your question by extracting them from the above code with:
snew=vertcat(s{:}); %Giving a different name to avoid confusion
tnew=vertcat(t{:});
Now you can make digraph
using snew
and tnew
and label edges with s{1}
, s{2}
, t{1}
and t{2}
.
For labeling the edges, you can use the following loop:
for k=1:length(s)
labeledge(h,s{k}, t{k}, ['label ',num2str(k)]);
end
This solves the issue of labeling if there are too many labels to make. Making the labels as first
, second
,.... would be cumbersome and may be unnecessary.
Output:
With the above modifications, you get the following output: