Browse code

starting som prediction fine-tuned class-performance visualisation

git-svn-id: https://svn.discofish.de/MATLAB/spmtoolbox/SVMCrossVal@112 83ab2cfd-5345-466c-8aeb-2b2739fb922d

Christoph Budziszewski authored on21/01/2009 16:34:25
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,771 @@
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
0 772
\ No newline at end of file