wolffd@0
|
1 function [x, y, h] = draw_graph(adj, labels, node_t, x, y, varargin)
|
wolffd@0
|
2 % DRAW_LAYOUT Draws a layout for a graph
|
wolffd@0
|
3 %
|
wolffd@0
|
4 % [X, Y, H] = DRAW_LAYOUT(ADJ, <LABELS, ISBOX, X, Y>)
|
wolffd@0
|
5 %
|
wolffd@0
|
6 % Inputs :
|
wolffd@0
|
7 % ADJ : Adjacency matrix (source, sink)
|
wolffd@0
|
8 % LABELS : Cell array containing labels <Default : '1':'N'>
|
wolffd@0
|
9 % ISBOX : 1 if node is a box, 0 if oval <Default : zeros>
|
wolffd@0
|
10 % X, Y, : Coordinates of nodes on the unit square <Default : calls make_layout>
|
wolffd@0
|
11 %
|
wolffd@0
|
12 % Outputs :
|
wolffd@0
|
13 % X, Y : Coordinates of nodes on the unit square
|
wolffd@0
|
14 % H : Object handles
|
wolffd@0
|
15 %
|
wolffd@0
|
16 % Usage Example : [x, y] = draw_layout([0 1;0 0], {'Hidden','Visible'}, [1 0]');
|
wolffd@0
|
17 %
|
wolffd@0
|
18 % h(i,1) is the text handle - color
|
wolffd@0
|
19 % h(i,2) is the circle handle - facecolor
|
wolffd@0
|
20 %
|
wolffd@0
|
21 % See also MAKE_LAYOUT
|
wolffd@0
|
22
|
wolffd@0
|
23 % Change History :
|
wolffd@0
|
24 % Date Time Prog Note
|
wolffd@0
|
25 % 13-Apr-2000 9:06 PM ATC Created under MATLAB 5.3.1.29215a (R11.1)
|
wolffd@0
|
26 %
|
wolffd@0
|
27 % ATC = Ali Taylan Cemgil,
|
wolffd@0
|
28 % SNN - University of Nijmegen, Department of Medical Physics and Biophysics
|
wolffd@0
|
29 % e-mail : cemgil@mbfys.kun.nl
|
wolffd@0
|
30
|
wolffd@0
|
31 adj = double(adj);
|
wolffd@0
|
32 N = size(adj,1);
|
wolffd@0
|
33 if nargin<2,
|
wolffd@0
|
34 labels = cellstr(int2str((1:N)'));
|
wolffd@0
|
35 end
|
wolffd@0
|
36
|
wolffd@0
|
37 if nargin<3,
|
wolffd@0
|
38 node_t = zeros(N,1);
|
wolffd@0
|
39 else
|
wolffd@0
|
40 node_t = node_t(:);
|
wolffd@0
|
41 end;
|
wolffd@0
|
42
|
wolffd@0
|
43 axis([0 1 0 1]);
|
wolffd@0
|
44 set(gca,'XTick',[],'YTick',[],'box','on');
|
wolffd@0
|
45 % axis('square');
|
wolffd@0
|
46 %colormap(flipud(gray));
|
wolffd@0
|
47
|
wolffd@0
|
48 if nargin<4,
|
wolffd@0
|
49 [x y] = make_layout(adj);
|
wolffd@0
|
50 end;
|
wolffd@0
|
51
|
wolffd@0
|
52 idx1 = find(node_t==0); h1 = []; wd1=[];
|
wolffd@0
|
53 if ~isempty(idx1)
|
wolffd@0
|
54 [h1 wd1] = textoval(x(idx1), y(idx1), labels(idx1), varargin{:});
|
wolffd@0
|
55 end;
|
wolffd@0
|
56
|
wolffd@0
|
57 idx2 = find(node_t~=0); h2 = []; wd2 = [];
|
wolffd@0
|
58 if ~isempty(idx2)
|
wolffd@0
|
59 [h2 wd2] = textbox(x(idx2), y(idx2), labels(idx2), varargin{:});
|
wolffd@0
|
60 end;
|
wolffd@0
|
61
|
wolffd@0
|
62 wd = zeros(size(wd1,1)+size(wd2,1),2);
|
wolffd@0
|
63 if ~isempty(idx1), wd(idx1, :) = wd1; end;
|
wolffd@0
|
64 if ~isempty(idx2), wd(idx2, :) = wd2; end;
|
wolffd@0
|
65
|
wolffd@0
|
66 % bug: this code assumes [x y] is the center of each box and oval, which
|
wolffd@0
|
67 % isn't exactly true.
|
wolffd@0
|
68 h_edge = [];
|
wolffd@0
|
69 for i=1:N,
|
wolffd@0
|
70 j = find(adj(i,:)==1);
|
wolffd@0
|
71 for k=j,
|
wolffd@0
|
72 if x(k)-x(i)==0,
|
wolffd@0
|
73 sign = 1;
|
wolffd@0
|
74 if y(i)>y(k), alpha = -pi/2; else alpha = pi/2; end;
|
wolffd@0
|
75 else
|
wolffd@0
|
76 alpha = atan((y(k)-y(i))/(x(k)-x(i)));
|
wolffd@0
|
77 if x(i)<x(k), sign = 1; else sign = -1; end;
|
wolffd@0
|
78 end;
|
wolffd@0
|
79 dy1 = sign.*wd(i,2).*sin(alpha); dx1 = sign.*wd(i,1).*cos(alpha);
|
wolffd@0
|
80 dy2 = sign.*wd(k,2).*sin(alpha); dx2 = sign.*wd(k,1).*cos(alpha);
|
wolffd@0
|
81 if adj(k,i)==0, % if directed edge
|
wolffd@0
|
82 h = arrow([x(i)+dx1 y(i)+dy1],[x(k)-dx2 y(k)-dy2],'BaseAngle',30);
|
wolffd@0
|
83 else
|
wolffd@0
|
84 h = line([x(i)+dx1 x(k)-dx2],[y(i)+dy1 y(k)-dy2]);
|
wolffd@0
|
85 adj(k,i)=-1; % Prevent drawing lines twice
|
wolffd@0
|
86 end;
|
wolffd@0
|
87 h_edge = [h_edge h];
|
wolffd@0
|
88 end;
|
wolffd@0
|
89 end;
|
wolffd@0
|
90
|
wolffd@0
|
91 color.box = 'black';
|
wolffd@0
|
92 color.text = color.box;
|
wolffd@0
|
93 color.edge = [1 1 1]*3/4;
|
wolffd@0
|
94 %color.edge = 'green';
|
wolffd@0
|
95 if ~isempty(idx1)
|
wolffd@0
|
96 set(h1(:,1),'Color',color.text)
|
wolffd@0
|
97 set(h1(:,2),'EdgeColor',color.box)
|
wolffd@0
|
98 end
|
wolffd@0
|
99 if ~isempty(idx2)
|
wolffd@0
|
100 set(h2(:,1),'Color',color.text)
|
wolffd@0
|
101 set(h2(:,2),'EdgeColor',color.box)
|
wolffd@0
|
102 end
|
wolffd@0
|
103 set(h_edge,'Color',color.edge)
|
wolffd@0
|
104
|
wolffd@0
|
105 if nargout>2,
|
wolffd@0
|
106 h = zeros(length(wd),2);
|
wolffd@0
|
107 if ~isempty(idx1),
|
wolffd@0
|
108 h(idx1,:) = h1;
|
wolffd@0
|
109 end;
|
wolffd@0
|
110 if ~isempty(idx2),
|
wolffd@0
|
111 h(idx2,:) = h2;
|
wolffd@0
|
112 end;
|
wolffd@0
|
113 end;
|
wolffd@0
|
114
|
wolffd@0
|
115 %%%%%
|
wolffd@0
|
116
|
wolffd@0
|
117 function [t, wd] = textoval(x, y, str, varargin)
|
wolffd@0
|
118 % TEXTOVAL Draws an oval around text objects
|
wolffd@0
|
119 %
|
wolffd@0
|
120 % [T, WIDTH] = TEXTOVAL(X, Y, STR)
|
wolffd@0
|
121 % [..] = TEXTOVAL(STR) % Interactive
|
wolffd@0
|
122 %
|
wolffd@0
|
123 % Inputs :
|
wolffd@0
|
124 % X, Y : Coordinates
|
wolffd@0
|
125 % TXT : Strings
|
wolffd@0
|
126 %
|
wolffd@0
|
127 % Outputs :
|
wolffd@0
|
128 % T : Object Handles
|
wolffd@0
|
129 % WIDTH : x and y Width of ovals
|
wolffd@0
|
130 %
|
wolffd@0
|
131 % Usage Example : [t] = textoval('Visit to Asia?');
|
wolffd@0
|
132 %
|
wolffd@0
|
133 %
|
wolffd@0
|
134 % Note :
|
wolffd@0
|
135 % See also TEXTBOX
|
wolffd@0
|
136
|
wolffd@0
|
137 % Uses :
|
wolffd@0
|
138
|
wolffd@0
|
139 % Change History :
|
wolffd@0
|
140 % Date Time Prog Note
|
wolffd@0
|
141 % 15-Jun-1998 10:36 AM ATC Created under MATLAB 5.1.0.421
|
wolffd@0
|
142 % 12-Mar-2004 10:00 AM minka Changed placement/sizing.
|
wolffd@0
|
143 %
|
wolffd@0
|
144 % ATC = Ali Taylan Cemgil,
|
wolffd@0
|
145 % SNN - University of Nijmegen, Department of Medical Physics and Biophysics
|
wolffd@0
|
146 % e-mail : cemgil@mbfys.kun.nl
|
wolffd@0
|
147
|
wolffd@0
|
148 temp = [];
|
wolffd@0
|
149 textProperties = {'BackgroundColor','Color','FontAngle','FontName','FontSize','FontUnits','FontWeight','Rotation'};
|
wolffd@0
|
150 varargin = argfilter(varargin,textProperties);
|
wolffd@0
|
151
|
wolffd@0
|
152 if nargin == 1
|
wolffd@0
|
153 str = x;
|
wolffd@0
|
154 end
|
wolffd@0
|
155 if ~isa(str,'cell') str=cellstr(str); end;
|
wolffd@0
|
156 N = length(str);
|
wolffd@0
|
157 wd = zeros(N,2);
|
wolffd@0
|
158 for i=1:N,
|
wolffd@0
|
159 if nargin == 1
|
wolffd@0
|
160 [x, y] = ginput(1);
|
wolffd@0
|
161 end
|
wolffd@0
|
162 tx = text(x(i),y(i),str{i},'HorizontalAlignment','center',varargin{:});
|
wolffd@0
|
163 % minka
|
wolffd@0
|
164 [ptc wx wy] = draw_oval(tx);
|
wolffd@0
|
165 wd(i,:) = [wx wy];
|
wolffd@0
|
166 % draw_oval will paint over the text, so need to redraw it
|
wolffd@0
|
167 delete(tx);
|
wolffd@0
|
168 tx = text(x(i),y(i),str{i},'HorizontalAlignment','center',varargin{:});
|
wolffd@0
|
169 temp = [temp; tx ptc];
|
wolffd@0
|
170 end
|
wolffd@0
|
171 if nargout>0, t = temp; end;
|
wolffd@0
|
172
|
wolffd@0
|
173 %%%%%%%%%
|
wolffd@0
|
174
|
wolffd@0
|
175
|
wolffd@0
|
176 function [ptc, wx, wy] = draw_oval(tx, x, y)
|
wolffd@0
|
177 % Draws an oval box around a tex object
|
wolffd@0
|
178 sz = get(tx,'Extent');
|
wolffd@0
|
179 % minka
|
wolffd@0
|
180 wy = 2/3*sz(4);
|
wolffd@0
|
181 wx = 2/3*sz(3);
|
wolffd@0
|
182 x = sz(1)+sz(3)/2;
|
wolffd@0
|
183 y = sz(2)+sz(4)/2;
|
wolffd@0
|
184 ptc = ellipse(x, y, wx, wy);
|
wolffd@0
|
185 set(ptc, 'FaceColor','w');
|
wolffd@0
|
186
|
wolffd@0
|
187
|
wolffd@0
|
188 %%%%%%%%%%%%%
|
wolffd@0
|
189
|
wolffd@0
|
190 function [p] = ellipse(x, y, rx, ry, c)
|
wolffd@0
|
191 % ELLIPSE Draws Ellipse shaped patch objects
|
wolffd@0
|
192 %
|
wolffd@0
|
193 % [<P>] = ELLIPSE(X, Y, Rx, Ry, C)
|
wolffd@0
|
194 %
|
wolffd@0
|
195 % Inputs :
|
wolffd@0
|
196 % X : N x 1 vector of x coordinates
|
wolffd@0
|
197 % Y : N x 1 vector of y coordinates
|
wolffd@0
|
198 % Rx, Ry : Radii
|
wolffd@0
|
199 % C : Color index
|
wolffd@0
|
200 %
|
wolffd@0
|
201 %
|
wolffd@0
|
202 % Outputs :
|
wolffd@0
|
203 % P = Handles of Ellipse shaped path objects
|
wolffd@0
|
204 %
|
wolffd@0
|
205 % Usage Example : [] = ellipse();
|
wolffd@0
|
206 %
|
wolffd@0
|
207 %
|
wolffd@0
|
208 % Note :
|
wolffd@0
|
209 % See also
|
wolffd@0
|
210
|
wolffd@0
|
211 % Uses :
|
wolffd@0
|
212
|
wolffd@0
|
213 % Change History :
|
wolffd@0
|
214 % Date Time Prog Note
|
wolffd@0
|
215 % 27-May-1998 9:55 AM ATC Created under MATLAB 5.1.0.421
|
wolffd@0
|
216
|
wolffd@0
|
217 % ATC = Ali Taylan Cemgil,
|
wolffd@0
|
218 % SNN - University of Nijmegen, Department of Medical Physics and Biophysics
|
wolffd@0
|
219 % e-mail : cemgil@mbfys.kun.nl
|
wolffd@0
|
220
|
wolffd@0
|
221 if (nargin < 2) error('Usage Example : e = ellipse([0 1],[0 -1],[1 0.5],[2 0.5]); '); end;
|
wolffd@0
|
222 if (nargin < 3) rx = 0.1; end;
|
wolffd@0
|
223 if (nargin < 4) ry = rx; end;
|
wolffd@0
|
224 if (nargin < 5) c = 1; end;
|
wolffd@0
|
225
|
wolffd@0
|
226 if length(c)==1, c = ones(size(x)).*c; end;
|
wolffd@0
|
227 if length(rx)==1, rx = ones(size(x)).*rx; end;
|
wolffd@0
|
228 if length(ry)==1, ry = ones(size(x)).*ry; end;
|
wolffd@0
|
229
|
wolffd@0
|
230 n = length(x);
|
wolffd@0
|
231 p = zeros(size(x));
|
wolffd@0
|
232 t = 0:pi/30:2*pi;
|
wolffd@0
|
233 for i=1:n,
|
wolffd@0
|
234 px = rx(i)*cos(t)+x(i);
|
wolffd@0
|
235 py = ry(i)*sin(t)+y(i);
|
wolffd@0
|
236 p(i) = patch(px,py,c(i));
|
wolffd@0
|
237 end;
|
wolffd@0
|
238
|
wolffd@0
|
239 if nargout>0, pp = p; end;
|
wolffd@0
|
240
|
wolffd@0
|
241 %%%%%
|
wolffd@0
|
242
|
wolffd@0
|
243 function [t, wd] = textbox(x,y,str,varargin)
|
wolffd@0
|
244 % TEXTBOX Draws A Box around the text
|
wolffd@0
|
245 %
|
wolffd@0
|
246 % [T, WIDTH] = TEXTBOX(X, Y, STR)
|
wolffd@0
|
247 % [..] = TEXTBOX(STR)
|
wolffd@0
|
248 %
|
wolffd@0
|
249 % Inputs :
|
wolffd@0
|
250 % X, Y : Coordinates
|
wolffd@0
|
251 % TXT : Strings
|
wolffd@0
|
252 %
|
wolffd@0
|
253 % Outputs :
|
wolffd@0
|
254 % T : Object Handles
|
wolffd@0
|
255 % WIDTH : x and y Width of boxes
|
wolffd@0
|
256 %%
|
wolffd@0
|
257 % Usage Example : t = textbox({'Ali','Veli','49','50'});
|
wolffd@0
|
258 %
|
wolffd@0
|
259 %
|
wolffd@0
|
260 % Note :
|
wolffd@0
|
261 % See also TEXTOVAL
|
wolffd@0
|
262
|
wolffd@0
|
263 % Uses :
|
wolffd@0
|
264
|
wolffd@0
|
265 % Change History :
|
wolffd@0
|
266 % Date Time Prog Note
|
wolffd@0
|
267 % 09-Jun-1998 11:43 AM ATC Created under MATLAB 5.1.0.421
|
wolffd@0
|
268 % 12-Mar-2004 10:00 AM minka Changed placement/sizing.
|
wolffd@0
|
269 %
|
wolffd@0
|
270 % ATC = Ali Taylan Cemgil,
|
wolffd@0
|
271 % SNN - University of Nijmegen, Department of Medical Physics and Biophysics
|
wolffd@0
|
272 % e-mail : cemgil@mbfys.kun.nl
|
wolffd@0
|
273
|
wolffd@0
|
274 temp = [];
|
wolffd@0
|
275 textProperties = {'BackgroundColor','Color','FontAngle','FontName','FontSize','FontUnits','FontWeight','Rotation'};
|
wolffd@0
|
276 varargin = argfilter(varargin,textProperties);
|
wolffd@0
|
277
|
wolffd@0
|
278 if nargin == 1
|
wolffd@0
|
279 str = x;
|
wolffd@0
|
280 end
|
wolffd@0
|
281 if ~isa(str,'cell') str=cellstr(str); end;
|
wolffd@0
|
282 N = length(str);
|
wolffd@0
|
283 wd = zeros(N,2);
|
wolffd@0
|
284 for i=1:N,
|
wolffd@0
|
285 if nargin == 1
|
wolffd@0
|
286 [x, y] = ginput(1);
|
wolffd@0
|
287 end
|
wolffd@0
|
288 tx = text(x(i),y(i),str{i},'HorizontalAlignment','center',varargin{:});
|
wolffd@0
|
289 % minka
|
wolffd@0
|
290 [ptc wx wy] = draw_box(tx);
|
wolffd@0
|
291 wd(i,:) = [wx wy];
|
wolffd@0
|
292 % draw_box will paint over the text, so need to redraw it
|
wolffd@0
|
293 delete(tx);
|
wolffd@0
|
294 tx = text(x(i),y(i),str{i},'HorizontalAlignment','center',varargin{:});
|
wolffd@0
|
295 temp = [temp; tx ptc];
|
wolffd@0
|
296 end;
|
wolffd@0
|
297
|
wolffd@0
|
298 if nargout>0, t = temp; end;
|
wolffd@0
|
299
|
wolffd@0
|
300
|
wolffd@0
|
301 function [ptc, wx, wy] = draw_box(tx)
|
wolffd@0
|
302 % Draws a box around a text object
|
wolffd@0
|
303 sz = get(tx,'Extent');
|
wolffd@0
|
304 % minka
|
wolffd@0
|
305 wy = 1/2*sz(4);
|
wolffd@0
|
306 wx = 1/2*sz(3);
|
wolffd@0
|
307 x = sz(1)+sz(3)/2;
|
wolffd@0
|
308 y = sz(2)+sz(4)/2;
|
wolffd@0
|
309 ptc = patch([x-wx x+wx x+wx x-wx], [y+wy y+wy y-wy y-wy],'w');
|
wolffd@0
|
310 set(ptc, 'FaceColor','w');
|
wolffd@0
|
311
|
wolffd@0
|
312
|
wolffd@0
|
313
|
wolffd@0
|
314 function args = argfilter(args,keep)
|
wolffd@0
|
315 %ARGFILTER Remove unwanted arguments.
|
wolffd@0
|
316 % ARGFILTER(ARGS,KEEP), where ARGS = {'arg1',value1,'arg2',value2,...},
|
wolffd@0
|
317 % returns a new argument list where only the arguments named in KEEP are
|
wolffd@0
|
318 % retained. KEEP is a character array or cell array of strings.
|
wolffd@0
|
319
|
wolffd@0
|
320 % Written by Tom Minka
|
wolffd@0
|
321
|
wolffd@0
|
322 if ischar(keep)
|
wolffd@0
|
323 keep = cellstr(keep);
|
wolffd@0
|
324 end
|
wolffd@0
|
325 i = 1;
|
wolffd@0
|
326 while i < length(args)
|
wolffd@0
|
327 if ~ismember(args{i},keep)
|
wolffd@0
|
328 args = args(setdiff(1:length(args),[i i+1]));
|
wolffd@0
|
329 else
|
wolffd@0
|
330 i = i + 2;
|
wolffd@0
|
331 end
|
wolffd@0
|
332 end
|