wolffd@0: function [S,m,l,t,s]=som_grid(varargin) wolffd@0: wolffd@0: %SOM_GRID Visualization of a SOM grid wolffd@0: % wolffd@0: % [sGrid,m,l,t,s]=som_grid(sGrid, ['argID', value, ...]) wolffd@0: % [sGrid,m,l,t,s]=som_grid(topol, ['argID', value, ...]) wolffd@0: % [sGrid,m,l,t,s]=som_grid(lattice, msize, ['argID', value, ...]) wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional) wolffd@0: % sGrid (struct) som_grid struct (see output arguments) wolffd@0: % topol (struct) map or topol struct for giving the topology wolffd@0: % (cell array) of form {'lattice', msize, ['shape']}. wolffd@0: % Default value for 'shape' is 'sheet'. wolffd@0: % lattice (string) 'hexa', 'rect' wolffd@0: % (matrix) size M x M, defines topological connections wolffd@0: % msize (vector) 1x2 vector defines the grid size, M=msize(1)*msize(2) wolffd@0: % ['argID',(string) Other arguments can be given as 'argID', value wolffd@0: % value] (varies) pairs. See list below for valid values. wolffd@0: % wolffd@0: % sGrid (struct) with fields S.msize, S.shape, S.lattice, S.coord, S.marker, wolffd@0: % S.markersize, S.markercolor, S.line, S.linewidth, S.linecolor, wolffd@0: % S.surf, S.label, S.labelsize, S.labelcolor wolffd@0: % m (matrix) handels to LINE objects (unit markers) wolffd@0: % l (matrix) handles to LINE objects (lines connecting the units) wolffd@0: % t (matrix) handles to TEXT objects (labels) wolffd@0: % s (scalar) handle to SURF object (surface between units) wolffd@0: % wolffd@0: % Here are the valid argument IDs (case insensitive) and wolffd@0: % associated values: wolffd@0: % 'Coord' Mx2 or Mx3 matrix of coordinates wolffd@0: % (default: according to lattice as in som_cplane) wolffd@0: % 'Marker' string 'o','+','x','*','v','^','<','>','h','s','d','p','.', wolffd@0: % 'none' or Mx1 cell or char array of these strings wolffd@0: % Default: 'o'. wolffd@0: % 'MarkerSize' scalar or Mx1 matrix of double. Default: 6. wolffd@0: % 'MarkerColor' ColorSpec or Mx3 matrix of RGB triples. Default: 'k'. wolffd@0: % 'Line' string '-',':','--' or '-.' or 'none'. Default: '-'. wolffd@0: % 'Surf' [], Mx1 or Mx3 matrix of RGB triples wolffd@0: % to define surface values. Default: [] = no surf. wolffd@0: % Note: shading is turned to 'interp'. wolffd@0: % 'LineWidth' scalar or MxM matrix, default: 0.5 wolffd@0: % 'LineColor' ColorSepc, MxMx3 matrix of RGB triples or a cell array wolffd@0: % of form {r g b} where r,g, and b are MxM wolffd@0: % (sparse) matrices of R,G, and B values wolffd@0: % 'Label' Mx1 char array, cell array of strings size MxL wolffd@0: % or [] to indicate no labels, default: [] = no labels. wolffd@0: % 'LabelSize' scalar wolffd@0: % 'LabelColor' ColorSpec or string 'none', default: 'g'. wolffd@0: % wolffd@0: % For more help, try 'type som_grid' or check out online documentation. wolffd@0: % See also SOM_CONNECTION, SOM_SHOW, SOM_CPLANE, SOM_SET, SCATTER, SCATTER3. wolffd@0: wolffd@0: %%%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_grid wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % To visualize the SOM grid in various ways wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % [sGrid,m,l,t,s]=som_grid(sGrid) wolffd@0: % [sGrid,m,l,t,s]=som_grid(sTopol) wolffd@0: % [sGrid,m,l,t,s]=som_grid(sMap) wolffd@0: % [sGrid,m,l,t,s]=som_grid({lattice, msize, [shape]}) wolffd@0: % [sGrid,m,l,t,s]=som_grid(lattice, msize) wolffd@0: % [sGrid,m,l,t,s]=som_grid(..., ['argID', value, ...]) wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % The SOM can be defined as a set of units (neurons) and their wolffd@0: % topological relations. This function is used to visualize these in wolffd@0: % various ways. The units may be drawn using different markers and wolffd@0: % colors, in different sizes and in different locations in 2D or wolffd@0: % 3D. However the topological neighborhood is limited to be wolffd@0: % 2-dimensional. The connections between these units may be drawn using wolffd@0: % lines having different thicknesses and colors. Labeling text may be wolffd@0: % plotted on the units. It is possible also to draw a surface between wolffd@0: % the units. The surface coloring is either indexed (one value per wolffd@0: % unit) or fixed RGB (a 1x3 RGB triple per unit). wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % Note: M is the number of map units. wolffd@0: % wolffd@0: % The first (or first two) argument may have various different types of values wolffd@0: % wolffd@0: % 1. sGrid (struct) som_grid struct (the output of this function) wolffd@0: % wolffd@0: % The struct initiates the visualization. The argID-value -pairs wolffd@0: % are used to alter the initiation. wolffd@0: % wolffd@0: % Following argument types may be used to give the topology for the grid wolffd@0: % wolffd@0: % 2. sTopol (struct) som_topol struct wolffd@0: % 3. sMap (struct) som_map struct (only topology matters) wolffd@0: % 4. {lattice, msize} or {lattice, msize, sheet} (cell array) wolffd@0: % - lattice must be 'hexa' or 'rect' wolffd@0: % - msize must be a 1x2 vector wolffd@0: % - shape (if specified) must be string 'sheet', 'cyl' or 'toroid' wolffd@0: % If shape is not given it is 'sheet' by default. wolffd@0: % 5. lattice (string or matrix) AND msize (1x2 vector) as two separate arguments wolffd@0: % - lattice may be string 'rect' or 'hexa' or a connection matrix wolffd@0: % (see SOM_CONNECTION) to define a free topology. This connection wolffd@0: % matrix is of size MxM and its element i,j (i','h','s','d', 'p','.', or 'none' wolffd@0: % give the same marker for each unit. wolffd@0: % (cell array) of size Mx1 of previous strings gives individual wolffd@0: % markers for each unit. wolffd@0: % wolffd@0: % 'MarkerSize' Size (pt) of unit markers, default is 6 (pt). wolffd@0: % (scalar) gives the same size for every unit. wolffd@0: % (matrix) Mx1 gives an individual size for each unit marker. wolffd@0: % wolffd@0: % 'MarkerColor' Unit marker colors, default is 'k' wolffd@0: % (ColorSpec) gives the same color each unit. wolffd@0: % (matrix) Mx3 of RGB triples gives individual color for each unit wolffd@0: % Note that indexed coloring - like in SOM_CPLANE - is wolffd@0: % not possible. If indexed coloring is needed, you can wolffd@0: % use SOM_NORMCOLOR to calculate RGB colors that wolffd@0: % emulate indexed coloring. However, the colors for the wolffd@0: % units are fixed, so changing colormap will not wolffd@0: % change the colors. wolffd@0: % wolffd@0: % 'Line' Line type, default is '-'. wolffd@0: % (string) '-',':','--' or '-.' or 'none'. Only one linetype in wolffd@0: % grid is allowed. wolffd@0: % wolffd@0: % 'LineWidth' Width of the topological connection lines (edges) wolffd@0: % (scalar) gives the same width for each line. Default is 0.5. wolffd@0: % (matrix) MxM sparse (or full) matrix gives individual width for wolffd@0: % each connection. The element (i,j), i= i are ignored in wolffd@0: % order to avoid ambiguous situations if the matrix would be wolffd@0: % non-symmetric. The "connections to oneself" is not drawn. wolffd@0: % wolffd@0: % Line width zero is valid and causes the line to disappear. wolffd@0: % wolffd@0: % 'LineColor' Color of connection lines, default is [0.9 0.9 0.9]. wolffd@0: % (ColorSpec) gives the same color for each line wolffd@0: % (matrix) MxMx3 matrix of RGB triples gives individual width for wolffd@0: % each connection. The element (i,j,:), i= i are ignored in order to avoid ambiguous situations wolffd@0: % if the matrix was non-symmetric. The "connections to oneself" wolffd@0: % is not drawn. wolffd@0: % wolffd@0: % wolffd@0: % 'Label' Labels for units, default is []. wolffd@0: % (empty) [] means no labels. wolffd@0: % (char array) of size Mx1. Element (i,:) has the label for unit i. wolffd@0: % (cell array) of size MxL consisting of sets of labels. Element {i,:} wolffd@0: % contains the labeling for unit i. wolffd@0: % In case of multiple labels, the labels for one unit are shown wolffd@0: % in one column centered at that unit. wolffd@0: % wolffd@0: % 'LabelSize' Text size of labels (points), default is 10. wolffd@0: % (scalar) Default is 10. wolffd@0: % wolffd@0: % 'LabelColor' Color of labels, default is 'c' (cyan). wolffd@0: % (ColorSpec) gives the same color for each label string 'xor' wolffd@0: % sets the colors automatically so that they differ wolffd@0: % from the background (using Matlab's built-in xor-color feature.) wolffd@0: % wolffd@0: % 'Surf' Surface between nodes, default is []. wolffd@0: % (empty) [] gives no surface wolffd@0: % (vector) Mx1 gives an indexed interpolated color surface between wolffd@0: % units using the actual colormap. wolffd@0: % (matrix) Mx3 matrix of RGB triples gives a interpolated color surface wolffd@0: % between units using fixed RGB colors. wolffd@0: % wolffd@0: % Note that the interpolation is done using Matlab's built-in wolffd@0: % color interpolation for SURF objects. wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sGrid (struct) with fields S.msize, S.shape, S.lattice, S.coord, S.marker, wolffd@0: % S.markersize, S.markercolor, S.line, S.linewidth, S.linecolor, wolffd@0: % S.surf, S.label, S.labelsize, S.labelcolor wolffd@0: % wolffd@0: % m (matrix) handels to LINE objects (unit markers) wolffd@0: % wolffd@0: % l (matrix) handles to LINE objects (lines connecting the units) wolffd@0: % wolffd@0: % t (matrix) handles to TEXT objects (labels) wolffd@0: % wolffd@0: % s (scalar) handle to SURF object (surface between units) wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % % Make map of size 15x10 on random data: wolffd@0: % wolffd@0: % map=som_make(rand(1000,4),'msize',[15 10], 'lattice', 'hexa'); wolffd@0: % wolffd@0: % % Draw the grid using two frist varable values as coordinates wolffd@0: % % and store the sGrid struct in varable S: wolffd@0: % wolffd@0: % S=som_grid(map, 'coord', map.codebook(:,[1 2])) wolffd@0: % wolffd@0: % %Define some things: wolffd@0: % % wolffd@0: % % Create a cell array of size 150x1 that divides map in to two label classes wolffd@0: % % 'circles' and 'squares' wolffd@0: % wolffd@0: % L(1:75,1)='o'; L(76:150,1)='s'; L = cellstr(L); wolffd@0: % wolffd@0: % % Create a coloring according to the 3rd variable according to current wolffd@0: % % colormap: wolffd@0: % wolffd@0: % C = som_normcolor(map.codebook(:,3)); wolffd@0: % wolffd@0: % % Change the visualization: use black lines, unit markers in M and unit wolffd@0: % % color in C, and set unit size to 10: wolffd@0: % wolffd@0: % S=som_grid(S, 'linecolor', 'k', 'marker', L, 'MarkerColor',C, ... wolffd@0: % 'MarkerSize', 10); wolffd@0: % wolffd@0: % % Do a new visualization, use indexed color surface calcualted from the wolffd@0: % % first variable, coordinates according to the lattice (default) but wolffd@0: % % no markers nor lines: wolffd@0: % wolffd@0: % S=som_grid(map,'line','none','marker','none','surf',map.codebook(:,1)); wolffd@0: % wolffd@0: % % Set coordinates according to three last varables wolffd@0: % wolffd@0: % som_grid(S,'coord',map.codebook(:,2:4)); wolffd@0: % wolffd@0: % % Create a random connection matrix R1 and the usual hexagonal wolffd@0: % % neighborhood connection matrix R2: wolffd@0: % wolffd@0: % R1=sparse(rand(150,150)>0.9); wolffd@0: % R2=som_connection(map); wolffd@0: % wolffd@0: % % Show these connections. Note that coordinates _must_ now be given wolffd@0: % % explicitly: we form default topological coordinates using wolffd@0: % % som_unit_coords. wolffd@0: % wolffd@0: % som_grid(R1,map.topol.msize,'coord',som_unit_coords(map)); wolffd@0: % som_grid(R2,map.topol.msize,'coord',som_unit_coords(map)); wolffd@0: % wolffd@0: % % Show connections (R1 AND R2) wolffd@0: % som_grid(R2.*R2,map.topol.msize,'coord',som_unit_coords(map)); wolffd@0: % wolffd@0: % OBJECT TAGS wolffd@0: % wolffd@0: % No tags are set. wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_show The basic map visualization routine wolffd@0: % som_cplane The basic component plane visualization wolffd@0: % som_connection The basic topological connections wolffd@0: % scatter Scatter plots wolffd@0: % scatter3 3-dimensional scatter plots wolffd@0: wolffd@0: % Copyright (c) 1999-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta Johan 061099 juuso 151199 310300 wolffd@0: wolffd@0: %% Init %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: True=1; False=0; % const. wolffd@0: m=[]; l=[]; t=[]; s=[]; % default values for outputs wolffd@0: Ref=som_set('som_grid'); % reference struct wolffd@0: wolffd@0: num_of_args=length(varargin); % numb. of varargins wolffd@0: wolffd@0: if num_of_args==0, wolffd@0: S=som_set('som_grid'); wolffd@0: return; wolffd@0: end wolffd@0: wolffd@0: switch class(varargin{1}) wolffd@0: case 'struct' wolffd@0: S=varargin{1}; wolffd@0: first_identifier=2; wolffd@0: if ~isfield(S,'type'), wolffd@0: error('Input struct is invalid: field ''type'' is missing.'); wolffd@0: end wolffd@0: switch S.type wolffd@0: case 'som_grid' wolffd@0: S=varargin{1}; wolffd@0: first_identifier=2; wolffd@0: case 'som_map' wolffd@0: Ref.lattice=S.topol.lattice; wolffd@0: Ref.msize=S.topol.msize; wolffd@0: Ref.shape=S.topol.shape; wolffd@0: S=Ref; wolffd@0: first_identifier=2; wolffd@0: case 'som_topol' wolffd@0: Ref.lattice=S.lattice; wolffd@0: Ref.msize=S.msize; wolffd@0: Ref.shape=S.shape; wolffd@0: S=Ref; wolffd@0: first_identifier=2; wolffd@0: otherwise wolffd@0: error('Input struct has to be of type som_grid, som_map or som_topol.'); wolffd@0: end wolffd@0: case 'cell' wolffd@0: S=varargin{1}; wolffd@0: first_identifier=2; wolffd@0: if vis_valuetype(S,{'topol_cell_no_shape'}), wolffd@0: Ref.lattice=S{1}; wolffd@0: Ref.msize=S{2}; wolffd@0: elseif vis_valuetype(S,{'topol_cell'}), wolffd@0: Ref.lattice=S{1}; wolffd@0: Ref.msize=S{2}; wolffd@0: Ref.shape=S{3}; wolffd@0: else wolffd@0: error(['The cell value for 1st argument has to be {lattice, msize}' ... wolffd@0: 'or {lattice, msize, shape}.']); wolffd@0: end wolffd@0: S=Ref; wolffd@0: case{'double','sparse','char'} wolffd@0: % Set defaults wolffd@0: S=Ref; wolffd@0: first_identifier=3; wolffd@0: if num_of_args<2, wolffd@0: error('Not enough input arguments.'); wolffd@0: end wolffd@0: S.lattice=varargin{1}; wolffd@0: S.msize=varargin{2}; wolffd@0: otherwise wolffd@0: error('Invalid input arguments!'); wolffd@0: end wolffd@0: wolffd@0: %% Check input args %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: for i=first_identifier:2:num_of_args, wolffd@0: if ischar(varargin{i}) & isfield(Ref,lower(varargin{i})), wolffd@0: if i+1>num_of_args, wolffd@0: error('Invalid identifier-value pairs or wrong argument order.'); wolffd@0: else wolffd@0: S=setfield(S,lower(varargin{i}),varargin{i+1}); wolffd@0: end wolffd@0: elseif ischar(varargin{i}), wolffd@0: error(['Identifier ''' varargin{i} ''' is unknown.']); wolffd@0: else wolffd@0: error('Invalid identifier-value pairs or wrong argument order.'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % msize wolffd@0: wolffd@0: if ~vis_valuetype(S.msize,{'1x2'}), wolffd@0: error('msize has to be a 1x2 vector.'); wolffd@0: end wolffd@0: munits=prod(S.msize); wolffd@0: wolffd@0: % Default coordinates according to negihborhood wolffd@0: wolffd@0: if isempty(S.coord), wolffd@0: if ischar(S.lattice), wolffd@0: switch S.lattice, wolffd@0: case{'hexa','rect'} wolffd@0: S.coord=som_vis_coords(S.lattice,S.msize); wolffd@0: otherwise wolffd@0: error('String value for lattice must be ''hexa'' or ''rect''.'); wolffd@0: end wolffd@0: else wolffd@0: error('Lattice is not ''hexa'' or ''rect'': coordinates must be given.'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % connections wolffd@0: wolffd@0: type=class(S.lattice); wolffd@0: switch type wolffd@0: case {'sparse','double'} % free topology wolffd@0: fixedline=False; wolffd@0: case 'char' % default topologies (hexa,char) wolffd@0: switch S.lattice wolffd@0: case 'hexa' wolffd@0: hexa=True; wolffd@0: case 'rect' wolffd@0: hexa=False; wolffd@0: otherwise wolffd@0: error('Unknown lattice or neighborhood.'); wolffd@0: end wolffd@0: wolffd@0: % If topology is hexa/rect but linetype, color etc. is wolffd@0: % not constant, the topology is set to free wolffd@0: wolffd@0: if size(S.linewidth,1)>1 | size(S.linecolor,1)>1 | ... wolffd@0: iscell(S.linecolor) % matrix or cell = not constant wolffd@0: fixedline=False; wolffd@0: S.lattice=som_connection({S.lattice,S.msize,S.shape}); wolffd@0: else wolffd@0: fixedline=True; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Check coordinate matrix size and set dummy zeros to z-axis wolffd@0: % if 2D coordinates (always 3D plots!) wolffd@0: wolffd@0: if ~vis_valuetype(S.coord,{[munits 2],[munits 3]}), wolffd@0: error('Coordinate matrix has wrong size.'); wolffd@0: elseif size(S.coord,2)==2, wolffd@0: S.coord(:,3)=0; wolffd@0: end wolffd@0: wolffd@0: % Fixed marker size, color, type? wolffd@0: wolffd@0: if size(S.markersize,1)>1 | size(S.markercolor,1)>1 | size(S.marker,1)>1 wolffd@0: fixedmarker=False; wolffd@0: else wolffd@0: fixedmarker=True; wolffd@0: end wolffd@0: wolffd@0: % Check labels wolffd@0: wolffd@0: if ~vis_valuetype(S.label,{'chararray','2Dcellarray_of_char'}) ... wolffd@0: & ~isempty(S.label), wolffd@0: error('Labels should be in a char array or cell array of strings.'); wolffd@0: elseif ischar(S.label) wolffd@0: S.label=cellstr(S.label); wolffd@0: end wolffd@0: wolffd@0: if size(S.label,1) ~= munits & ~isempty(S.label), wolffd@0: error('Number of labels and map size do not match.'); wolffd@0: end wolffd@0: wolffd@0: % Check line width, marker size, marker color, wolffd@0: % label size label color and surf sizes&types: wolffd@0: wolffd@0: if ~vis_valuetype(S.linewidth,{[munits munits] [1 1]}), wolffd@0: error('LineWidth matrix value has wrong size or dimension.'); wolffd@0: elseif any(S.linewidth(:)<0), wolffd@0: error('All elements of LineWidth must be non-negative.'); wolffd@0: elseif ~vis_valuetype(S.markersize,{[munits 1] [1 1]}), wolffd@0: error('MarkerSize matrix value has wrong size or dimension.'); wolffd@0: elseif any(S.markersize(:)<0), wolffd@0: error('All elements of MarkerSize must be non-negative.'); wolffd@0: elseif ~vis_valuetype(S.markercolor,{'1x3rgb','colorstyle'}) & ... wolffd@0: ~vis_valuetype(S.markercolor,{[munits 3],'nx3rgb'},'all'), wolffd@0: error('MarkerColor should be a ColorSpec or Mx3 matrix of RGB triples.'); wolffd@0: elseif ~vis_valuetype(S.labelcolor,{'1x3rgb','colorstyle','xor'}), wolffd@0: error('LabelColor shoud be a ColorSpec or ''xor'' or ''none''.') wolffd@0: elseif ~vis_valuetype(S.labelsize,{'1x1'}) wolffd@0: error('LabelSize should be a scalar.'); wolffd@0: elseif ~isempty(S.surf) & ~vis_valuetype(S.surf,{[munits 1] [munits 3]}); wolffd@0: error('Surf matrix value has wrong size or dimension.'); wolffd@0: end wolffd@0: wolffd@0: % Check marker type & size wolffd@0: wolffd@0: if vis_valuetype(S.marker,{'cellcolumn_of_char'}) wolffd@0: % Don't bother to check the mareker strings in this case wolffd@0: % let the plot3 handle them; it returns quite understandable wolffd@0: % error messages, anyway wolffd@0: wolffd@0: if ~size(S.marker) == [munits 1], wolffd@0: error(['Marker should be one of Matlab''s valid marker type,' ... wolffd@0: ' string ''none'' or a Mx1 cell array of these.']); wolffd@0: end wolffd@0: elseif ~vis_valuetype(S.marker,{'markerstyle','none'}), wolffd@0: error(['Marker should be one of Matlab''s valid marker type,' ... wolffd@0: ' string ''none'' or a Mx1 cell array of these.']); wolffd@0: end wolffd@0: wolffd@0: % Check line type & size: only one line style allowed wolffd@0: wolffd@0: if ~vis_valuetype(S.line,{'linestyle','none'}) wolffd@0: error(['Line should be a valid Matlab''s line style string or' ... wolffd@0: ' string ''none''.']); wolffd@0: end wolffd@0: wolffd@0: % Check line color wolffd@0: wolffd@0: if iscell(S.linecolor), wolffd@0: if ndims(S.linecolor) ~= 2 | any(size(S.linecolor) ~= [1 3]), wolffd@0: error('Cell input for LineColor should be of form {r,g,b}.') wolffd@0: elseif ~vis_valuetype(S.linecolor{1},{[munits munits],'nxn[0,1]'},'all')| ... wolffd@0: ~vis_valuetype(S.linecolor{2},{[munits munits],'nxn[0,1]'},'all')| ... wolffd@0: ~vis_valuetype(S.linecolor{3},{[munits munits],'nxn[0,1]'},'all'), wolffd@0: error(['In cell input {r,g,b} some matrix r,g or b is invalid: ' ... wolffd@0: 'Size must be MxM and values in interval [0,1].']); wolffd@0: end wolffd@0: elseif ~vis_valuetype(S.linecolor,{'colorstyle','1x3rgb'}) & ... wolffd@0: ~vis_valuetype(S.linecolor,{'nxnx3rgb', [munits munits 3]},'all'), wolffd@0: error('Invalid LineColor: see help text for valid values.'), wolffd@0: elseif vis_valuetype(S.linecolor, {'none'}), wolffd@0: error('LineColor ''none'' not allowed: set Line to ''none'' instead.'); wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% Action wolffd@0: wolffd@0: memhold=ishold; % take hold state wolffd@0: if ~memhold wolffd@0: cla; wolffd@0: end wolffd@0: hold on; wolffd@0: wolffd@0: % Set surf if it exist wolffd@0: wolffd@0: if ~isempty(S.surf), wolffd@0: for i=1:3, wolffd@0: s(:,:,i)=reshape(S.coord(:,i),S.msize); wolffd@0: end wolffd@0: s(:,:,4:3+size(S.surf,2))=reshape(S.surf,[S.msize size(S.surf,2)]); wolffd@0: s=surf(s(:,:,1),s(:,:,2),s(:,:,3),s(:,:,4:end)); wolffd@0: set(s,'EdgeColor','none','Marker','none','FaceColor','interp'); wolffd@0: end wolffd@0: wolffd@0: wolffd@0: if fixedline, wolffd@0: % Line properties are fixed: draw fast, but wolffd@0: % if line is set to 'none' set empty handle ans skip wolffd@0: if strcmp(S.line,'none') wolffd@0: l={}; wolffd@0: else wolffd@0: p1=reshape(S.coord, [S.msize 3]); wolffd@0: p2=zeros(size(p1)-[0 1 0]); wolffd@0: p2(1:2:end,:,:)=p1(1:2:end,2:end,:); wolffd@0: p2(2:2:end,:,:)=p1(2:2:end,1:end-1,:); wolffd@0: wolffd@0: l{1}=plot3(p1(:,:,1), p1(:,:,2), p1(:,:,3), ... wolffd@0: 'Color', S.linecolor(1,:), ... wolffd@0: 'LineWidth', S.linewidth(1), ... wolffd@0: 'LineStyle', S.line); wolffd@0: l{2}=plot3(p1(:,:,1)', p1(:,:,2)', p1(:,:,3)', ... wolffd@0: 'Color', S.linecolor(1,:), ... wolffd@0: 'LineWidth', S.linewidth(1), ... wolffd@0: 'LineStyle', S.line); wolffd@0: if hexa, wolffd@0: l{3}=plot3(p2(:,:,1), p2(:,:,2), p2(:,:,3), ... wolffd@0: 'Color', S.linecolor(1,:), ... wolffd@0: 'LineWidth', S.linewidth(1), ... wolffd@0: 'LineStyle', S.line); wolffd@0: end wolffd@0: end wolffd@0: l=cat(1,l{:}); wolffd@0: else wolffd@0: % Variable properties: draw connection by connection wolffd@0: wolffd@0: [I,J,lw]=find(S.lattice); wolffd@0: x=[S.coord(I,1)'; S.coord(J,1)']; wolffd@0: y=[S.coord(I,2)'; S.coord(J,2)']; wolffd@0: z=[S.coord(I,3)'; S.coord(J,3)']; wolffd@0: if S.linewidth(1)==0, wolffd@0: linewidth=0.5; wolffd@0: else wolffd@0: linewidth=S.linewidth(1); wolffd@0: end wolffd@0: if ndims(S.linecolor) ~= 3 wolffd@0: if isstr(S.linecolor) wolffd@0: l=plot3(x, y, z, ... wolffd@0: 'Color', S.linecolor, ... wolffd@0: 'LineWidth', linewidth, ... wolffd@0: 'LineStyle',S.line); wolffd@0: else wolffd@0: if iscell(S.linecolor) wolffd@0: lcolor=[S.linecolor{1}(1,1) S.linecolor{2}(1,1) S.linecolor{3}(1,1)]; wolffd@0: l=plot3(x, y, z, ... wolffd@0: 'Color', lcolor, ... wolffd@0: 'LineWidth', linewidth, ... wolffd@0: 'LineStyle',S.line); wolffd@0: else wolffd@0: l=plot3(x, y, z, ... wolffd@0: 'Color', S.linecolor(1,:), ... wolffd@0: 'LineWidth', linewidth, ... wolffd@0: 'LineStyle',S.line); wolffd@0: end wolffd@0: end wolffd@0: else wolffd@0: l=plot3(x, y, z, ... wolffd@0: 'Color', S.linecolor(1,1,:), ... wolffd@0: 'LineWidth', linewidth, ... wolffd@0: 'LineStyle',S.line); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if fixedmarker, wolffd@0: wolffd@0: % If marker is set to 'none' skip and set empty handle wolffd@0: if strcmp(S.marker,'none') wolffd@0: m=[]; wolffd@0: else wolffd@0: % Fixed markers: draw all in one command wolffd@0: wolffd@0: m=plot3(S.coord(:,1), S.coord(:,2), S.coord(:,3), ... wolffd@0: 'LineStyle', 'none', ... wolffd@0: 'Marker', S.marker, ... wolffd@0: 'MarkerSize', S.markersize(1), ... wolffd@0: 'MarkerFaceColor', S.markercolor(1,:), ... wolffd@0: 'MarkerEdgeColor', S.markercolor(1,:)); wolffd@0: end wolffd@0: else wolffd@0: % Variable marker properties: draw marker by marker wolffd@0: wolffd@0: x=[S.coord(:,1)'; S.coord(:,1)']; wolffd@0: y=[S.coord(:,2)'; S.coord(:,2)']; wolffd@0: z=[S.coord(:,3)'; S.coord(:,3)']; wolffd@0: if iscell(S.marker) wolffd@0: marker=S.marker{1}; wolffd@0: else wolffd@0: marker=S.marker(1); wolffd@0: end wolffd@0: sz=max(S.markersize(1),0.1); wolffd@0: m=plot3(x, y, z, ... wolffd@0: 'LineStyle', 'none', ... wolffd@0: 'Marker', marker, ... wolffd@0: 'MarkerSize', sz, ... wolffd@0: 'MarkerFaceColor', S.markercolor(1,:), ... wolffd@0: 'MarkerEdgeColor', S.markercolor(1,:)); wolffd@0: end wolffd@0: wolffd@0: L=length(l); wolffd@0: n=munits; wolffd@0: wolffd@0: %%% Set variable properties %%% wolffd@0: wolffd@0: % Line width wolffd@0: wolffd@0: if length(S.linewidth)>1 wolffd@0: lwidth=diag(S.linewidth(I,J)); wolffd@0: wolffd@0: % Handle zero width wolffd@0: iszero=(lwidth == 0);lwidth(iszero)=0.5; wolffd@0: for i=1:length(l), wolffd@0: set(l(i),'LineWidth', lwidth(i)); wolffd@0: end wolffd@0: if ~isempty(iszero), % zero width wolffd@0: set(l(iszero),'Visible','off'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Line color wolffd@0: wolffd@0: if size(S.linecolor,1)>1 | iscell(S.linecolor) wolffd@0: if length(size(S.linecolor)) == 3 | iscell(S.linecolor) wolffd@0: if ~iscell(S.linecolor) wolffd@0: for i=1:L wolffd@0: set(l(i),'Color',S.linecolor(I(i),J(i),:)); wolffd@0: end wolffd@0: else wolffd@0: for i=1:L wolffd@0: lcolor=[S.linecolor{1}(I(i),J(i)),... wolffd@0: S.linecolor{2}(I(i),J(i)),... wolffd@0: S.linecolor{3}(I(i),J(i))]; wolffd@0: set(l(i),'Color',lcolor); wolffd@0: end wolffd@0: end wolffd@0: else wolffd@0: for i=1:L, wolffd@0: set(l(i),'Color', S.linecolor(I(i),:)); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Marker size wolffd@0: wolffd@0: if length(S.markersize)>1 wolffd@0: % handle zero size wolffd@0: iszero=find(~S.markersize); wolffd@0: S.markersize(iszero)=1; wolffd@0: for i=1:n, wolffd@0: set(m(i),'MarkerSize', S.markersize(i)); wolffd@0: end wolffd@0: if ~isempty(iszero), % zero size wolffd@0: set(m(iszero),'Visible','off'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Marker type wolffd@0: wolffd@0: if size(S.marker,1)>1 wolffd@0: S.marker=char(S.marker); wolffd@0: for i=1:n, wolffd@0: set(m(i),'Marker', S.marker(i)); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Marker color wolffd@0: wolffd@0: if size(S.markercolor,1)>1 wolffd@0: for i=1:n, wolffd@0: set(m(i),'MarkerFaceColor', S.markercolor(i,:), ... wolffd@0: 'MarkerEdgeColor', S.markercolor(i,:)); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Set labels if they exist wolffd@0: wolffd@0: if ~isempty(S.label) wolffd@0: if vis_valuetype(S.labelcolor,{'xor'}), wolffd@0: S.labelcolor='g'; wolffd@0: XOR=1; wolffd@0: else wolffd@0: XOR=0; wolffd@0: end wolffd@0: if vis_valuetype(S.labelcolor,{'none'}), wolffd@0: S.labelcolor='g'; wolffd@0: VIS = 1; wolffd@0: else wolffd@0: VIS = 0; wolffd@0: end wolffd@0: for i=1:size(S.label,1), wolffd@0: L=cat(1,S.label(i,:)); wolffd@0: for j=length(L):-1:1, wolffd@0: if isempty(L{j}), wolffd@0: L=L(1:end-1); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if isempty(L), wolffd@0: L=''; wolffd@0: end wolffd@0: t(i)=text(S.coord(i,1), S.coord(i,2), S.coord(i,3), L,... wolffd@0: 'FontSize', S.labelsize, 'Color',S.labelcolor, ... wolffd@0: 'HorizontalAlignment', 'center'); wolffd@0: end wolffd@0: if XOR wolffd@0: set(t,'EraseMode','xor'); wolffd@0: end wolffd@0: if VIS wolffd@0: set(t,'Visible','off'); wolffd@0: end wolffd@0: else wolffd@0: t=[]; wolffd@0: end wolffd@0: wolffd@0: %% Set hold state wolffd@0: wolffd@0: if ~memhold, wolffd@0: hold off; wolffd@0: end wolffd@0: wolffd@0: if nargout==0, wolffd@0: clear S m l t s; wolffd@0: end