Mercurial > hg > camir-aes2014
comparison toolboxes/MIRtoolbox1.3.2/somtoolbox/som_grid.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function [S,m,l,t,s]=som_grid(varargin) | |
2 | |
3 %SOM_GRID Visualization of a SOM grid | |
4 % | |
5 % [sGrid,m,l,t,s]=som_grid(sGrid, ['argID', value, ...]) | |
6 % [sGrid,m,l,t,s]=som_grid(topol, ['argID', value, ...]) | |
7 % [sGrid,m,l,t,s]=som_grid(lattice, msize, ['argID', value, ...]) | |
8 % | |
9 % Input and output arguments ([]'s are optional) | |
10 % sGrid (struct) som_grid struct (see output arguments) | |
11 % topol (struct) map or topol struct for giving the topology | |
12 % (cell array) of form {'lattice', msize, ['shape']}. | |
13 % Default value for 'shape' is 'sheet'. | |
14 % lattice (string) 'hexa', 'rect' | |
15 % (matrix) size M x M, defines topological connections | |
16 % msize (vector) 1x2 vector defines the grid size, M=msize(1)*msize(2) | |
17 % ['argID',(string) Other arguments can be given as 'argID', value | |
18 % value] (varies) pairs. See list below for valid values. | |
19 % | |
20 % sGrid (struct) with fields S.msize, S.shape, S.lattice, S.coord, S.marker, | |
21 % S.markersize, S.markercolor, S.line, S.linewidth, S.linecolor, | |
22 % S.surf, S.label, S.labelsize, S.labelcolor | |
23 % m (matrix) handels to LINE objects (unit markers) | |
24 % l (matrix) handles to LINE objects (lines connecting the units) | |
25 % t (matrix) handles to TEXT objects (labels) | |
26 % s (scalar) handle to SURF object (surface between units) | |
27 % | |
28 % Here are the valid argument IDs (case insensitive) and | |
29 % associated values: | |
30 % 'Coord' Mx2 or Mx3 matrix of coordinates | |
31 % (default: according to lattice as in som_cplane) | |
32 % 'Marker' string 'o','+','x','*','v','^','<','>','h','s','d','p','.', | |
33 % 'none' or Mx1 cell or char array of these strings | |
34 % Default: 'o'. | |
35 % 'MarkerSize' scalar or Mx1 matrix of double. Default: 6. | |
36 % 'MarkerColor' ColorSpec or Mx3 matrix of RGB triples. Default: 'k'. | |
37 % 'Line' string '-',':','--' or '-.' or 'none'. Default: '-'. | |
38 % 'Surf' [], Mx1 or Mx3 matrix of RGB triples | |
39 % to define surface values. Default: [] = no surf. | |
40 % Note: shading is turned to 'interp'. | |
41 % 'LineWidth' scalar or MxM matrix, default: 0.5 | |
42 % 'LineColor' ColorSepc, MxMx3 matrix of RGB triples or a cell array | |
43 % of form {r g b} where r,g, and b are MxM | |
44 % (sparse) matrices of R,G, and B values | |
45 % 'Label' Mx1 char array, cell array of strings size MxL | |
46 % or [] to indicate no labels, default: [] = no labels. | |
47 % 'LabelSize' scalar | |
48 % 'LabelColor' ColorSpec or string 'none', default: 'g'. | |
49 % | |
50 % For more help, try 'type som_grid' or check out online documentation. | |
51 % See also SOM_CONNECTION, SOM_SHOW, SOM_CPLANE, SOM_SET, SCATTER, SCATTER3. | |
52 | |
53 %%%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
54 % | |
55 % som_grid | |
56 % | |
57 % PURPOSE | |
58 % | |
59 % To visualize the SOM grid in various ways | |
60 % | |
61 % SYNTAX | |
62 % | |
63 % [sGrid,m,l,t,s]=som_grid(sGrid) | |
64 % [sGrid,m,l,t,s]=som_grid(sTopol) | |
65 % [sGrid,m,l,t,s]=som_grid(sMap) | |
66 % [sGrid,m,l,t,s]=som_grid({lattice, msize, [shape]}) | |
67 % [sGrid,m,l,t,s]=som_grid(lattice, msize) | |
68 % [sGrid,m,l,t,s]=som_grid(..., ['argID', value, ...]) | |
69 % | |
70 % DESCRIPTION | |
71 % | |
72 % The SOM can be defined as a set of units (neurons) and their | |
73 % topological relations. This function is used to visualize these in | |
74 % various ways. The units may be drawn using different markers and | |
75 % colors, in different sizes and in different locations in 2D or | |
76 % 3D. However the topological neighborhood is limited to be | |
77 % 2-dimensional. The connections between these units may be drawn using | |
78 % lines having different thicknesses and colors. Labeling text may be | |
79 % plotted on the units. It is possible also to draw a surface between | |
80 % the units. The surface coloring is either indexed (one value per | |
81 % unit) or fixed RGB (a 1x3 RGB triple per unit). | |
82 % | |
83 % REQUIRED INPUT ARGUMENTS | |
84 % | |
85 % Note: M is the number of map units. | |
86 % | |
87 % The first (or first two) argument may have various different types of values | |
88 % | |
89 % 1. sGrid (struct) som_grid struct (the output of this function) | |
90 % | |
91 % The struct initiates the visualization. The argID-value -pairs | |
92 % are used to alter the initiation. | |
93 % | |
94 % Following argument types may be used to give the topology for the grid | |
95 % | |
96 % 2. sTopol (struct) som_topol struct | |
97 % 3. sMap (struct) som_map struct (only topology matters) | |
98 % 4. {lattice, msize} or {lattice, msize, sheet} (cell array) | |
99 % - lattice must be 'hexa' or 'rect' | |
100 % - msize must be a 1x2 vector | |
101 % - shape (if specified) must be string 'sheet', 'cyl' or 'toroid' | |
102 % If shape is not given it is 'sheet' by default. | |
103 % 5. lattice (string or matrix) AND msize (1x2 vector) as two separate arguments | |
104 % - lattice may be string 'rect' or 'hexa' or a connection matrix | |
105 % (see SOM_CONNECTION) to define a free topology. This connection | |
106 % matrix is of size MxM and its element i,j (i<j) is set | |
107 % to 1 if there is a connection between units i and j, otherwise to | |
108 % zero. Shape is set to 'sheet' by default. Shape does not have any | |
109 % meaning if a free topology is specified, anyway. | |
110 % - msize must be a 1x2 vector | |
111 % | |
112 % In cases 2...5 the sGrid structure is initiated by default values | |
113 % which are set in SOM_SET. These include black markers 'o' (6pt), | |
114 % light gray conncection lines (graph edges), unit coordinates | |
115 % according to the lattice ('hexa','rect'), no labels, and no | |
116 % surface. | |
117 % | |
118 % OPTIONAL INPUT ARGUMENTS | |
119 % | |
120 % Note: M is the number of map units. | |
121 % | |
122 % Here is a list of the valid arguments IDs and the associated | |
123 % values (identifiers are case insensitive): | |
124 % | |
125 % 'Coord' Unit coordinates | |
126 % This defines the coordinates of the units. Default: the | |
127 % topological coordinates (calculated as in function | |
128 % SOM_VIS_COORDS and SOM_CPLANE). If the topology is free | |
129 % (lattice is a connection matrix) this argument is obligatory! | |
130 % (matrix) size Mx2 of 2D coordinates for each unit | |
131 % (matrix) size Mx3 of 3D coordinates for each unit | |
132 % | |
133 % 'Marker' Unit markers, default is 'o'. | |
134 % (string) 'o','+','x','*','v','^','<','>','h','s','d', 'p','.', or 'none' | |
135 % give the same marker for each unit. | |
136 % (cell array) of size Mx1 of previous strings gives individual | |
137 % markers for each unit. | |
138 % | |
139 % 'MarkerSize' Size (pt) of unit markers, default is 6 (pt). | |
140 % (scalar) gives the same size for every unit. | |
141 % (matrix) Mx1 gives an individual size for each unit marker. | |
142 % | |
143 % 'MarkerColor' Unit marker colors, default is 'k' | |
144 % (ColorSpec) gives the same color each unit. | |
145 % (matrix) Mx3 of RGB triples gives individual color for each unit | |
146 % Note that indexed coloring - like in SOM_CPLANE - is | |
147 % not possible. If indexed coloring is needed, you can | |
148 % use SOM_NORMCOLOR to calculate RGB colors that | |
149 % emulate indexed coloring. However, the colors for the | |
150 % units are fixed, so changing colormap will not | |
151 % change the colors. | |
152 % | |
153 % 'Line' Line type, default is '-'. | |
154 % (string) '-',':','--' or '-.' or 'none'. Only one linetype in | |
155 % grid is allowed. | |
156 % | |
157 % 'LineWidth' Width of the topological connection lines (edges) | |
158 % (scalar) gives the same width for each line. Default is 0.5. | |
159 % (matrix) MxM sparse (or full) matrix gives individual width for | |
160 % each connection. The element (i,j), i<j, gives the line width for | |
161 % connection between nodes i and j. (The sparse form is | |
162 % recommended for saving memory, a full matrix works as well, | |
163 % of course). Note that only the elements satisfying i<j | |
164 % matter - as the elememts for which j >= i are ignored in | |
165 % order to avoid ambiguous situations if the matrix would be | |
166 % non-symmetric. The "connections to oneself" is not drawn. | |
167 % | |
168 % Line width zero is valid and causes the line to disappear. | |
169 % | |
170 % 'LineColor' Color of connection lines, default is [0.9 0.9 0.9]. | |
171 % (ColorSpec) gives the same color for each line | |
172 % (matrix) MxMx3 matrix of RGB triples gives individual width for | |
173 % each connection. The element (i,j,:), i<j, gives the RGB triple for | |
174 % line between nodes i and j. | |
175 % (cell array) of three sparse (or full) matrices {r,g,b} where | |
176 % r(i,j), g(i,j) and b(i,j) gives the R,G, and B values in the RGB | |
177 % triple for the line between nodes i and j. (The motivation for this | |
178 % form is the fact that a 3D arrays can't use sparse format in | |
179 % Matlab version 5.1.) | |
180 % | |
181 % Note that only the elements satisfying i<j matter - the elememts | |
182 % for which j >= i are ignored in order to avoid ambiguous situations | |
183 % if the matrix was non-symmetric. The "connections to oneself" | |
184 % is not drawn. | |
185 % | |
186 % | |
187 % 'Label' Labels for units, default is []. | |
188 % (empty) [] means no labels. | |
189 % (char array) of size Mx1. Element (i,:) has the label for unit i. | |
190 % (cell array) of size MxL consisting of sets of labels. Element {i,:} | |
191 % contains the labeling for unit i. | |
192 % In case of multiple labels, the labels for one unit are shown | |
193 % in one column centered at that unit. | |
194 % | |
195 % 'LabelSize' Text size of labels (points), default is 10. | |
196 % (scalar) Default is 10. | |
197 % | |
198 % 'LabelColor' Color of labels, default is 'c' (cyan). | |
199 % (ColorSpec) gives the same color for each label string 'xor' | |
200 % sets the colors automatically so that they differ | |
201 % from the background (using Matlab's built-in xor-color feature.) | |
202 % | |
203 % 'Surf' Surface between nodes, default is []. | |
204 % (empty) [] gives no surface | |
205 % (vector) Mx1 gives an indexed interpolated color surface between | |
206 % units using the actual colormap. | |
207 % (matrix) Mx3 matrix of RGB triples gives a interpolated color surface | |
208 % between units using fixed RGB colors. | |
209 % | |
210 % Note that the interpolation is done using Matlab's built-in | |
211 % color interpolation for SURF objects. | |
212 % | |
213 % OUTPUT ARGUMENTS | |
214 % | |
215 % sGrid (struct) with fields S.msize, S.shape, S.lattice, S.coord, S.marker, | |
216 % S.markersize, S.markercolor, S.line, S.linewidth, S.linecolor, | |
217 % S.surf, S.label, S.labelsize, S.labelcolor | |
218 % | |
219 % m (matrix) handels to LINE objects (unit markers) | |
220 % | |
221 % l (matrix) handles to LINE objects (lines connecting the units) | |
222 % | |
223 % t (matrix) handles to TEXT objects (labels) | |
224 % | |
225 % s (scalar) handle to SURF object (surface between units) | |
226 % | |
227 % EXAMPLES | |
228 % | |
229 % % Make map of size 15x10 on random data: | |
230 % | |
231 % map=som_make(rand(1000,4),'msize',[15 10], 'lattice', 'hexa'); | |
232 % | |
233 % % Draw the grid using two frist varable values as coordinates | |
234 % % and store the sGrid struct in varable S: | |
235 % | |
236 % S=som_grid(map, 'coord', map.codebook(:,[1 2])) | |
237 % | |
238 % %Define some things: | |
239 % % | |
240 % % Create a cell array of size 150x1 that divides map in to two label classes | |
241 % % 'circles' and 'squares' | |
242 % | |
243 % L(1:75,1)='o'; L(76:150,1)='s'; L = cellstr(L); | |
244 % | |
245 % % Create a coloring according to the 3rd variable according to current | |
246 % % colormap: | |
247 % | |
248 % C = som_normcolor(map.codebook(:,3)); | |
249 % | |
250 % % Change the visualization: use black lines, unit markers in M and unit | |
251 % % color in C, and set unit size to 10: | |
252 % | |
253 % S=som_grid(S, 'linecolor', 'k', 'marker', L, 'MarkerColor',C, ... | |
254 % 'MarkerSize', 10); | |
255 % | |
256 % % Do a new visualization, use indexed color surface calcualted from the | |
257 % % first variable, coordinates according to the lattice (default) but | |
258 % % no markers nor lines: | |
259 % | |
260 % S=som_grid(map,'line','none','marker','none','surf',map.codebook(:,1)); | |
261 % | |
262 % % Set coordinates according to three last varables | |
263 % | |
264 % som_grid(S,'coord',map.codebook(:,2:4)); | |
265 % | |
266 % % Create a random connection matrix R1 and the usual hexagonal | |
267 % % neighborhood connection matrix R2: | |
268 % | |
269 % R1=sparse(rand(150,150)>0.9); | |
270 % R2=som_connection(map); | |
271 % | |
272 % % Show these connections. Note that coordinates _must_ now be given | |
273 % % explicitly: we form default topological coordinates using | |
274 % % som_unit_coords. | |
275 % | |
276 % som_grid(R1,map.topol.msize,'coord',som_unit_coords(map)); | |
277 % som_grid(R2,map.topol.msize,'coord',som_unit_coords(map)); | |
278 % | |
279 % % Show connections (R1 AND R2) | |
280 % som_grid(R2.*R2,map.topol.msize,'coord',som_unit_coords(map)); | |
281 % | |
282 % OBJECT TAGS | |
283 % | |
284 % No tags are set. | |
285 % | |
286 % SEE ALSO | |
287 % | |
288 % som_show The basic map visualization routine | |
289 % som_cplane The basic component plane visualization | |
290 % som_connection The basic topological connections | |
291 % scatter Scatter plots | |
292 % scatter3 3-dimensional scatter plots | |
293 | |
294 % Copyright (c) 1999-2000 by the SOM toolbox programming team. | |
295 % http://www.cis.hut.fi/projects/somtoolbox/ | |
296 | |
297 % Version 2.0beta Johan 061099 juuso 151199 310300 | |
298 | |
299 %% Init %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
300 | |
301 True=1; False=0; % const. | |
302 m=[]; l=[]; t=[]; s=[]; % default values for outputs | |
303 Ref=som_set('som_grid'); % reference struct | |
304 | |
305 num_of_args=length(varargin); % numb. of varargins | |
306 | |
307 if num_of_args==0, | |
308 S=som_set('som_grid'); | |
309 return; | |
310 end | |
311 | |
312 switch class(varargin{1}) | |
313 case 'struct' | |
314 S=varargin{1}; | |
315 first_identifier=2; | |
316 if ~isfield(S,'type'), | |
317 error('Input struct is invalid: field ''type'' is missing.'); | |
318 end | |
319 switch S.type | |
320 case 'som_grid' | |
321 S=varargin{1}; | |
322 first_identifier=2; | |
323 case 'som_map' | |
324 Ref.lattice=S.topol.lattice; | |
325 Ref.msize=S.topol.msize; | |
326 Ref.shape=S.topol.shape; | |
327 S=Ref; | |
328 first_identifier=2; | |
329 case 'som_topol' | |
330 Ref.lattice=S.lattice; | |
331 Ref.msize=S.msize; | |
332 Ref.shape=S.shape; | |
333 S=Ref; | |
334 first_identifier=2; | |
335 otherwise | |
336 error('Input struct has to be of type som_grid, som_map or som_topol.'); | |
337 end | |
338 case 'cell' | |
339 S=varargin{1}; | |
340 first_identifier=2; | |
341 if vis_valuetype(S,{'topol_cell_no_shape'}), | |
342 Ref.lattice=S{1}; | |
343 Ref.msize=S{2}; | |
344 elseif vis_valuetype(S,{'topol_cell'}), | |
345 Ref.lattice=S{1}; | |
346 Ref.msize=S{2}; | |
347 Ref.shape=S{3}; | |
348 else | |
349 error(['The cell value for 1st argument has to be {lattice, msize}' ... | |
350 'or {lattice, msize, shape}.']); | |
351 end | |
352 S=Ref; | |
353 case{'double','sparse','char'} | |
354 % Set defaults | |
355 S=Ref; | |
356 first_identifier=3; | |
357 if num_of_args<2, | |
358 error('Not enough input arguments.'); | |
359 end | |
360 S.lattice=varargin{1}; | |
361 S.msize=varargin{2}; | |
362 otherwise | |
363 error('Invalid input arguments!'); | |
364 end | |
365 | |
366 %% Check input args %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
367 | |
368 for i=first_identifier:2:num_of_args, | |
369 if ischar(varargin{i}) & isfield(Ref,lower(varargin{i})), | |
370 if i+1>num_of_args, | |
371 error('Invalid identifier-value pairs or wrong argument order.'); | |
372 else | |
373 S=setfield(S,lower(varargin{i}),varargin{i+1}); | |
374 end | |
375 elseif ischar(varargin{i}), | |
376 error(['Identifier ''' varargin{i} ''' is unknown.']); | |
377 else | |
378 error('Invalid identifier-value pairs or wrong argument order.'); | |
379 end | |
380 end | |
381 | |
382 % msize | |
383 | |
384 if ~vis_valuetype(S.msize,{'1x2'}), | |
385 error('msize has to be a 1x2 vector.'); | |
386 end | |
387 munits=prod(S.msize); | |
388 | |
389 % Default coordinates according to negihborhood | |
390 | |
391 if isempty(S.coord), | |
392 if ischar(S.lattice), | |
393 switch S.lattice, | |
394 case{'hexa','rect'} | |
395 S.coord=som_vis_coords(S.lattice,S.msize); | |
396 otherwise | |
397 error('String value for lattice must be ''hexa'' or ''rect''.'); | |
398 end | |
399 else | |
400 error('Lattice is not ''hexa'' or ''rect'': coordinates must be given.'); | |
401 end | |
402 end | |
403 | |
404 % connections | |
405 | |
406 type=class(S.lattice); | |
407 switch type | |
408 case {'sparse','double'} % free topology | |
409 fixedline=False; | |
410 case 'char' % default topologies (hexa,char) | |
411 switch S.lattice | |
412 case 'hexa' | |
413 hexa=True; | |
414 case 'rect' | |
415 hexa=False; | |
416 otherwise | |
417 error('Unknown lattice or neighborhood.'); | |
418 end | |
419 | |
420 % If topology is hexa/rect but linetype, color etc. is | |
421 % not constant, the topology is set to free | |
422 | |
423 if size(S.linewidth,1)>1 | size(S.linecolor,1)>1 | ... | |
424 iscell(S.linecolor) % matrix or cell = not constant | |
425 fixedline=False; | |
426 S.lattice=som_connection({S.lattice,S.msize,S.shape}); | |
427 else | |
428 fixedline=True; | |
429 end | |
430 end | |
431 | |
432 % Check coordinate matrix size and set dummy zeros to z-axis | |
433 % if 2D coordinates (always 3D plots!) | |
434 | |
435 if ~vis_valuetype(S.coord,{[munits 2],[munits 3]}), | |
436 error('Coordinate matrix has wrong size.'); | |
437 elseif size(S.coord,2)==2, | |
438 S.coord(:,3)=0; | |
439 end | |
440 | |
441 % Fixed marker size, color, type? | |
442 | |
443 if size(S.markersize,1)>1 | size(S.markercolor,1)>1 | size(S.marker,1)>1 | |
444 fixedmarker=False; | |
445 else | |
446 fixedmarker=True; | |
447 end | |
448 | |
449 % Check labels | |
450 | |
451 if ~vis_valuetype(S.label,{'chararray','2Dcellarray_of_char'}) ... | |
452 & ~isempty(S.label), | |
453 error('Labels should be in a char array or cell array of strings.'); | |
454 elseif ischar(S.label) | |
455 S.label=cellstr(S.label); | |
456 end | |
457 | |
458 if size(S.label,1) ~= munits & ~isempty(S.label), | |
459 error('Number of labels and map size do not match.'); | |
460 end | |
461 | |
462 % Check line width, marker size, marker color, | |
463 % label size label color and surf sizes&types: | |
464 | |
465 if ~vis_valuetype(S.linewidth,{[munits munits] [1 1]}), | |
466 error('LineWidth matrix value has wrong size or dimension.'); | |
467 elseif any(S.linewidth(:)<0), | |
468 error('All elements of LineWidth must be non-negative.'); | |
469 elseif ~vis_valuetype(S.markersize,{[munits 1] [1 1]}), | |
470 error('MarkerSize matrix value has wrong size or dimension.'); | |
471 elseif any(S.markersize(:)<0), | |
472 error('All elements of MarkerSize must be non-negative.'); | |
473 elseif ~vis_valuetype(S.markercolor,{'1x3rgb','colorstyle'}) & ... | |
474 ~vis_valuetype(S.markercolor,{[munits 3],'nx3rgb'},'all'), | |
475 error('MarkerColor should be a ColorSpec or Mx3 matrix of RGB triples.'); | |
476 elseif ~vis_valuetype(S.labelcolor,{'1x3rgb','colorstyle','xor'}), | |
477 error('LabelColor shoud be a ColorSpec or ''xor'' or ''none''.') | |
478 elseif ~vis_valuetype(S.labelsize,{'1x1'}) | |
479 error('LabelSize should be a scalar.'); | |
480 elseif ~isempty(S.surf) & ~vis_valuetype(S.surf,{[munits 1] [munits 3]}); | |
481 error('Surf matrix value has wrong size or dimension.'); | |
482 end | |
483 | |
484 % Check marker type & size | |
485 | |
486 if vis_valuetype(S.marker,{'cellcolumn_of_char'}) | |
487 % Don't bother to check the mareker strings in this case | |
488 % let the plot3 handle them; it returns quite understandable | |
489 % error messages, anyway | |
490 | |
491 if ~size(S.marker) == [munits 1], | |
492 error(['Marker should be one of Matlab''s valid marker type,' ... | |
493 ' string ''none'' or a Mx1 cell array of these.']); | |
494 end | |
495 elseif ~vis_valuetype(S.marker,{'markerstyle','none'}), | |
496 error(['Marker should be one of Matlab''s valid marker type,' ... | |
497 ' string ''none'' or a Mx1 cell array of these.']); | |
498 end | |
499 | |
500 % Check line type & size: only one line style allowed | |
501 | |
502 if ~vis_valuetype(S.line,{'linestyle','none'}) | |
503 error(['Line should be a valid Matlab''s line style string or' ... | |
504 ' string ''none''.']); | |
505 end | |
506 | |
507 % Check line color | |
508 | |
509 if iscell(S.linecolor), | |
510 if ndims(S.linecolor) ~= 2 | any(size(S.linecolor) ~= [1 3]), | |
511 error('Cell input for LineColor should be of form {r,g,b}.') | |
512 elseif ~vis_valuetype(S.linecolor{1},{[munits munits],'nxn[0,1]'},'all')| ... | |
513 ~vis_valuetype(S.linecolor{2},{[munits munits],'nxn[0,1]'},'all')| ... | |
514 ~vis_valuetype(S.linecolor{3},{[munits munits],'nxn[0,1]'},'all'), | |
515 error(['In cell input {r,g,b} some matrix r,g or b is invalid: ' ... | |
516 'Size must be MxM and values in interval [0,1].']); | |
517 end | |
518 elseif ~vis_valuetype(S.linecolor,{'colorstyle','1x3rgb'}) & ... | |
519 ~vis_valuetype(S.linecolor,{'nxnx3rgb', [munits munits 3]},'all'), | |
520 error('Invalid LineColor: see help text for valid values.'), | |
521 elseif vis_valuetype(S.linecolor, {'none'}), | |
522 error('LineColor ''none'' not allowed: set Line to ''none'' instead.'); | |
523 end | |
524 | |
525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
526 %% Action | |
527 | |
528 memhold=ishold; % take hold state | |
529 if ~memhold | |
530 cla; | |
531 end | |
532 hold on; | |
533 | |
534 % Set surf if it exist | |
535 | |
536 if ~isempty(S.surf), | |
537 for i=1:3, | |
538 s(:,:,i)=reshape(S.coord(:,i),S.msize); | |
539 end | |
540 s(:,:,4:3+size(S.surf,2))=reshape(S.surf,[S.msize size(S.surf,2)]); | |
541 s=surf(s(:,:,1),s(:,:,2),s(:,:,3),s(:,:,4:end)); | |
542 set(s,'EdgeColor','none','Marker','none','FaceColor','interp'); | |
543 end | |
544 | |
545 | |
546 if fixedline, | |
547 % Line properties are fixed: draw fast, but | |
548 % if line is set to 'none' set empty handle ans skip | |
549 if strcmp(S.line,'none') | |
550 l={}; | |
551 else | |
552 p1=reshape(S.coord, [S.msize 3]); | |
553 p2=zeros(size(p1)-[0 1 0]); | |
554 p2(1:2:end,:,:)=p1(1:2:end,2:end,:); | |
555 p2(2:2:end,:,:)=p1(2:2:end,1:end-1,:); | |
556 | |
557 l{1}=plot3(p1(:,:,1), p1(:,:,2), p1(:,:,3), ... | |
558 'Color', S.linecolor(1,:), ... | |
559 'LineWidth', S.linewidth(1), ... | |
560 'LineStyle', S.line); | |
561 l{2}=plot3(p1(:,:,1)', p1(:,:,2)', p1(:,:,3)', ... | |
562 'Color', S.linecolor(1,:), ... | |
563 'LineWidth', S.linewidth(1), ... | |
564 'LineStyle', S.line); | |
565 if hexa, | |
566 l{3}=plot3(p2(:,:,1), p2(:,:,2), p2(:,:,3), ... | |
567 'Color', S.linecolor(1,:), ... | |
568 'LineWidth', S.linewidth(1), ... | |
569 'LineStyle', S.line); | |
570 end | |
571 end | |
572 l=cat(1,l{:}); | |
573 else | |
574 % Variable properties: draw connection by connection | |
575 | |
576 [I,J,lw]=find(S.lattice); | |
577 x=[S.coord(I,1)'; S.coord(J,1)']; | |
578 y=[S.coord(I,2)'; S.coord(J,2)']; | |
579 z=[S.coord(I,3)'; S.coord(J,3)']; | |
580 if S.linewidth(1)==0, | |
581 linewidth=0.5; | |
582 else | |
583 linewidth=S.linewidth(1); | |
584 end | |
585 if ndims(S.linecolor) ~= 3 | |
586 if isstr(S.linecolor) | |
587 l=plot3(x, y, z, ... | |
588 'Color', S.linecolor, ... | |
589 'LineWidth', linewidth, ... | |
590 'LineStyle',S.line); | |
591 else | |
592 if iscell(S.linecolor) | |
593 lcolor=[S.linecolor{1}(1,1) S.linecolor{2}(1,1) S.linecolor{3}(1,1)]; | |
594 l=plot3(x, y, z, ... | |
595 'Color', lcolor, ... | |
596 'LineWidth', linewidth, ... | |
597 'LineStyle',S.line); | |
598 else | |
599 l=plot3(x, y, z, ... | |
600 'Color', S.linecolor(1,:), ... | |
601 'LineWidth', linewidth, ... | |
602 'LineStyle',S.line); | |
603 end | |
604 end | |
605 else | |
606 l=plot3(x, y, z, ... | |
607 'Color', S.linecolor(1,1,:), ... | |
608 'LineWidth', linewidth, ... | |
609 'LineStyle',S.line); | |
610 end | |
611 end | |
612 | |
613 if fixedmarker, | |
614 | |
615 % If marker is set to 'none' skip and set empty handle | |
616 if strcmp(S.marker,'none') | |
617 m=[]; | |
618 else | |
619 % Fixed markers: draw all in one command | |
620 | |
621 m=plot3(S.coord(:,1), S.coord(:,2), S.coord(:,3), ... | |
622 'LineStyle', 'none', ... | |
623 'Marker', S.marker, ... | |
624 'MarkerSize', S.markersize(1), ... | |
625 'MarkerFaceColor', S.markercolor(1,:), ... | |
626 'MarkerEdgeColor', S.markercolor(1,:)); | |
627 end | |
628 else | |
629 % Variable marker properties: draw marker by marker | |
630 | |
631 x=[S.coord(:,1)'; S.coord(:,1)']; | |
632 y=[S.coord(:,2)'; S.coord(:,2)']; | |
633 z=[S.coord(:,3)'; S.coord(:,3)']; | |
634 if iscell(S.marker) | |
635 marker=S.marker{1}; | |
636 else | |
637 marker=S.marker(1); | |
638 end | |
639 sz=max(S.markersize(1),0.1); | |
640 m=plot3(x, y, z, ... | |
641 'LineStyle', 'none', ... | |
642 'Marker', marker, ... | |
643 'MarkerSize', sz, ... | |
644 'MarkerFaceColor', S.markercolor(1,:), ... | |
645 'MarkerEdgeColor', S.markercolor(1,:)); | |
646 end | |
647 | |
648 L=length(l); | |
649 n=munits; | |
650 | |
651 %%% Set variable properties %%% | |
652 | |
653 % Line width | |
654 | |
655 if length(S.linewidth)>1 | |
656 lwidth=diag(S.linewidth(I,J)); | |
657 | |
658 % Handle zero width | |
659 iszero=(lwidth == 0);lwidth(iszero)=0.5; | |
660 for i=1:length(l), | |
661 set(l(i),'LineWidth', lwidth(i)); | |
662 end | |
663 if ~isempty(iszero), % zero width | |
664 set(l(iszero),'Visible','off'); | |
665 end | |
666 end | |
667 | |
668 % Line color | |
669 | |
670 if size(S.linecolor,1)>1 | iscell(S.linecolor) | |
671 if length(size(S.linecolor)) == 3 | iscell(S.linecolor) | |
672 if ~iscell(S.linecolor) | |
673 for i=1:L | |
674 set(l(i),'Color',S.linecolor(I(i),J(i),:)); | |
675 end | |
676 else | |
677 for i=1:L | |
678 lcolor=[S.linecolor{1}(I(i),J(i)),... | |
679 S.linecolor{2}(I(i),J(i)),... | |
680 S.linecolor{3}(I(i),J(i))]; | |
681 set(l(i),'Color',lcolor); | |
682 end | |
683 end | |
684 else | |
685 for i=1:L, | |
686 set(l(i),'Color', S.linecolor(I(i),:)); | |
687 end | |
688 end | |
689 end | |
690 | |
691 % Marker size | |
692 | |
693 if length(S.markersize)>1 | |
694 % handle zero size | |
695 iszero=find(~S.markersize); | |
696 S.markersize(iszero)=1; | |
697 for i=1:n, | |
698 set(m(i),'MarkerSize', S.markersize(i)); | |
699 end | |
700 if ~isempty(iszero), % zero size | |
701 set(m(iszero),'Visible','off'); | |
702 end | |
703 end | |
704 | |
705 % Marker type | |
706 | |
707 if size(S.marker,1)>1 | |
708 S.marker=char(S.marker); | |
709 for i=1:n, | |
710 set(m(i),'Marker', S.marker(i)); | |
711 end | |
712 end | |
713 | |
714 % Marker color | |
715 | |
716 if size(S.markercolor,1)>1 | |
717 for i=1:n, | |
718 set(m(i),'MarkerFaceColor', S.markercolor(i,:), ... | |
719 'MarkerEdgeColor', S.markercolor(i,:)); | |
720 end | |
721 end | |
722 | |
723 % Set labels if they exist | |
724 | |
725 if ~isempty(S.label) | |
726 if vis_valuetype(S.labelcolor,{'xor'}), | |
727 S.labelcolor='g'; | |
728 XOR=1; | |
729 else | |
730 XOR=0; | |
731 end | |
732 if vis_valuetype(S.labelcolor,{'none'}), | |
733 S.labelcolor='g'; | |
734 VIS = 1; | |
735 else | |
736 VIS = 0; | |
737 end | |
738 for i=1:size(S.label,1), | |
739 L=cat(1,S.label(i,:)); | |
740 for j=length(L):-1:1, | |
741 if isempty(L{j}), | |
742 L=L(1:end-1); | |
743 end | |
744 end | |
745 | |
746 if isempty(L), | |
747 L=''; | |
748 end | |
749 t(i)=text(S.coord(i,1), S.coord(i,2), S.coord(i,3), L,... | |
750 'FontSize', S.labelsize, 'Color',S.labelcolor, ... | |
751 'HorizontalAlignment', 'center'); | |
752 end | |
753 if XOR | |
754 set(t,'EraseMode','xor'); | |
755 end | |
756 if VIS | |
757 set(t,'Visible','off'); | |
758 end | |
759 else | |
760 t=[]; | |
761 end | |
762 | |
763 %% Set hold state | |
764 | |
765 if ~memhold, | |
766 hold off; | |
767 end | |
768 | |
769 if nargout==0, | |
770 clear S m l t s; | |
771 end |