wolffd@0
|
1 function graph_to_dot(G, varargin)
|
wolffd@0
|
2 % DAG_TO_DOT Make a file representing the directed graph in dotty format.
|
wolffd@0
|
3 % dag_to_dot(G, ...)
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % Optional arguments should be passed as name/value pairs [default]
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % 'filename' - if omitted, we write to 'tmp.dot', convert this to 'tmp.ps',
|
wolffd@0
|
8 % and then call ghostview automatically
|
wolffd@0
|
9 % 'arc_label' - arc_label{i,j} is a string attached to the i->j arc. [""]
|
wolffd@0
|
10 % 'node_label' - node_label{i} is a string attached to node i. ["i"]
|
wolffd@0
|
11 % 'width' - width in inches [10]
|
wolffd@0
|
12 % 'height' - height in inches [10]
|
wolffd@0
|
13 % 'leftright' - 1 means layout left-to-right, 0 means top-to-bottom [0]
|
wolffd@0
|
14 % 'directed' - 1 means use directed arcs, 0 means undirected [1]
|
wolffd@0
|
15 %
|
wolffd@0
|
16 % For details on dotty, See http://www.research.att.com/sw/tools/graphviz
|
wolffd@0
|
17 %
|
wolffd@0
|
18 % Example:
|
wolffd@0
|
19 % G = rand(5,5);
|
wolffd@0
|
20 % names = cell(5,5);
|
wolffd@0
|
21 % names{1,2} = 'arc 1-2';
|
wolffd@0
|
22 % graph_to_dot(G, 'arc_label', names)
|
wolffd@0
|
23 % or graph_to_dot(G, 'arc_label', 'numbers') % prints value of G(i,j) on i->j arc
|
wolffd@0
|
24
|
wolffd@0
|
25 % Kevin Murphy, 1998
|
wolffd@0
|
26
|
wolffd@0
|
27 % set default args
|
wolffd@0
|
28 filename = [];
|
wolffd@0
|
29 node_label = [];
|
wolffd@0
|
30 arc_label = [];
|
wolffd@0
|
31 width = 10;
|
wolffd@0
|
32 height = 10;
|
wolffd@0
|
33 leftright = 0;
|
wolffd@0
|
34 directed = 1;
|
wolffd@0
|
35 % get optional args
|
wolffd@0
|
36 args = varargin;
|
wolffd@0
|
37 for i=1:2:length(args)
|
wolffd@0
|
38 switch args{i}
|
wolffd@0
|
39 case 'filename', filename = args{i+1};
|
wolffd@0
|
40 case 'node_label', node_label = args{i+1};
|
wolffd@0
|
41 case 'arc_label', arc_label = args{i+1};
|
wolffd@0
|
42 case 'width', width = args{i+1};
|
wolffd@0
|
43 case 'height', height = args{i+1};
|
wolffd@0
|
44 case 'leftright', leftright = args{i+1};
|
wolffd@0
|
45 case 'directed', directed = args{i+1};
|
wolffd@0
|
46 end
|
wolffd@0
|
47 end
|
wolffd@0
|
48
|
wolffd@0
|
49 if isstr(arc_label) & strcmp(arc_label, 'numbers')
|
wolffd@0
|
50 N = length(G);
|
wolffd@0
|
51 arc_label = cell(N,N);
|
wolffd@0
|
52 for i=1:N
|
wolffd@0
|
53 for j=1:N
|
wolffd@0
|
54 arc_label{i,j} = sprintf('%4.2f', G(i,j));
|
wolffd@0
|
55 end
|
wolffd@0
|
56 end
|
wolffd@0
|
57 end
|
wolffd@0
|
58
|
wolffd@0
|
59 if isempty(filename)
|
wolffd@0
|
60 make_file(G, 'tmp.dot', node_label, arc_label, width, height, leftright, directed);
|
wolffd@0
|
61 if isunix
|
wolffd@0
|
62 !dot -Tps tmp.dot -o tmp.ps
|
wolffd@0
|
63
|
wolffd@0
|
64 !gs tmp.ps &
|
wolffd@0
|
65 else
|
wolffd@0
|
66 dos('dot -Tps tmp.dot -o tmp.ps');
|
wolffd@0
|
67 dos('gsview32 tmp.ps &');
|
wolffd@0
|
68 end
|
wolffd@0
|
69 else
|
wolffd@0
|
70
|
wolffd@0
|
71
|
wolffd@0
|
72 make_file(G, filename, node_label, arc_label, width, height, leftright, directed);
|
wolffd@0
|
73 end
|
wolffd@0
|
74
|
wolffd@0
|
75
|
wolffd@0
|
76 %%%%%%
|
wolffd@0
|
77
|
wolffd@0
|
78 function make_file(G, filename, node_label, arc_label, width, height, leftright, directed)
|
wolffd@0
|
79
|
wolffd@0
|
80 n = length(G);
|
wolffd@0
|
81 fid = fopen(filename, 'w');
|
wolffd@0
|
82 if directed
|
wolffd@0
|
83 fprintf(fid, 'digraph G {\n');
|
wolffd@0
|
84 else
|
wolffd@0
|
85 fprintf(fid, 'graph G {\n');
|
wolffd@0
|
86 end
|
wolffd@0
|
87 fprintf(fid, 'center = 1;\n');
|
wolffd@0
|
88 fprintf(fid, 'size=\"%d,%d\";\n', width, height);
|
wolffd@0
|
89 if leftright
|
wolffd@0
|
90 fprintf(fid, 'rankdir=LR;\n');
|
wolffd@0
|
91 end
|
wolffd@0
|
92 for i=1:n
|
wolffd@0
|
93 if isempty(node_label)
|
wolffd@0
|
94 fprintf(fid, '%d;\n', i);
|
wolffd@0
|
95 else
|
wolffd@0
|
96 fprintf(fid, '%d [ label = "%s" ];\n', i, node_label{i});
|
wolffd@0
|
97 end
|
wolffd@0
|
98 end
|
wolffd@0
|
99 if directed
|
wolffd@0
|
100 for i=1:n
|
wolffd@0
|
101 cs = children(G,i);
|
wolffd@0
|
102 for j=1:length(cs)
|
wolffd@0
|
103 c = cs(j);
|
wolffd@0
|
104 if isempty(arc_label)
|
wolffd@0
|
105 fprintf(fid, '%d -> %d;\n', i, c);
|
wolffd@0
|
106 else
|
wolffd@0
|
107 fprintf(fid, '%d -> %d [label="%s"];\n', i, c, arc_label{i,c});
|
wolffd@0
|
108 end
|
wolffd@0
|
109 end
|
wolffd@0
|
110 end
|
wolffd@0
|
111 else
|
wolffd@0
|
112 for i=1:n
|
wolffd@0
|
113 ns = intersect(neighbors(G,i), i+1:n); % remove duplicate arcs
|
wolffd@0
|
114 for j=1:length(ns)
|
wolffd@0
|
115 c = ns(j);
|
wolffd@0
|
116 if isempty(arc_label)
|
wolffd@0
|
117 fprintf(fid, '%d -- %d [dir=none];\n', i, c);
|
wolffd@0
|
118 else
|
wolffd@0
|
119 fprintf(fid, '%d -- %d [label="%s",dir=none];\n', i, c, arc_label{i,c});
|
wolffd@0
|
120 end
|
wolffd@0
|
121 end
|
wolffd@0
|
122 end
|
wolffd@0
|
123 end
|
wolffd@0
|
124 fprintf(fid, '\n}');
|
wolffd@0
|
125 fclose(fid);
|
wolffd@0
|
126
|
wolffd@0
|
127
|
wolffd@0
|
128
|
wolffd@0
|
129 %%%%%%%%%%%%%%%
|
wolffd@0
|
130
|
wolffd@0
|
131 function cs = children(adj_mat, i, t)
|
wolffd@0
|
132 % CHILDREN Return the indices of a node's children in sorted order
|
wolffd@0
|
133 % c = children(adj_mat, i, t)
|
wolffd@0
|
134 %
|
wolffd@0
|
135 % t is an optional argument: if present, dag is assumed to be a 2-slice DBN
|
wolffd@0
|
136
|
wolffd@0
|
137 if nargin < 3
|
wolffd@0
|
138 cs = find(adj_mat(i,:));
|
wolffd@0
|
139 else
|
wolffd@0
|
140 if t==1
|
wolffd@0
|
141 cs = find(adj_mat(i,:));
|
wolffd@0
|
142 else
|
wolffd@0
|
143 ss = length(adj_mat)/2;
|
wolffd@0
|
144 j = i+ss;
|
wolffd@0
|
145 cs = find(adj_mat(j,:)) + (t-2)*ss;
|
wolffd@0
|
146 end
|
wolffd@0
|
147 end
|
wolffd@0
|
148
|
wolffd@0
|
149 %%%%%%%%%%%%
|
wolffd@0
|
150
|
wolffd@0
|
151 function ps = parents(adj_mat, i)
|
wolffd@0
|
152 % PARENTS Return the list of parents of node i
|
wolffd@0
|
153 % ps = parents(adj_mat, i)
|
wolffd@0
|
154
|
wolffd@0
|
155 ps = find(adj_mat(:,i))';
|
wolffd@0
|
156
|
wolffd@0
|
157 %%%%%%%%%%%%%
|
wolffd@0
|
158
|
wolffd@0
|
159 function ns = neighbors(adj_mat, i)
|
wolffd@0
|
160 % NEIGHBORS Find the parents and children of a node in a graph.
|
wolffd@0
|
161 % ns = neighbors(adj_mat, i)
|
wolffd@0
|
162
|
wolffd@0
|
163 ns = union(children(adj_mat, i), parents(adj_mat, i));
|
wolffd@0
|
164
|
wolffd@0
|
165
|
wolffd@0
|
166
|