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