wolffd@0: function color=som_clustercolor(m, class, colorcode) wolffd@0: wolffd@0: % SOM_CLUSTERCOLOR Sets map unit coloring according to classification wolffd@0: % wolffd@0: % syntax 1: color = som_clustercolor(m, class, [colorcode]) wolffd@0: % syntax 2: color = som_clustercolor(class, colormatrix) wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % m (struct) map or topol struct wolffd@0: % (cell array) of form {str,[m1 m2]} where str = 'hexa' wolffd@0: % or 'rect' and [m1 m2] = msize. wolffd@0: % class (matrix) Mxn matrix of integers (class labels) wolffd@0: % where M is the number of map units and each wolffd@0: % column gives some classification for the units. wolffd@0: % colorcode (string) 'rgb1', 'rgb2' (default), 'rgb3', 'rgb4', 'hsv'. wolffd@0: % colormatrix (matrix) Mx3 matrix of RGB triplets giving the wolffd@0: % initial color code for each unit. wolffd@0: % color (matrix) size Mx3xn of RGB triplets giving the wolffd@0: % resulting color code for each unit wolffd@0: % wolffd@0: % The function gives a color coding by class and location for the wolffd@0: % map units. The color is determined by calculating the mean of the wolffd@0: % initial RGB values of units belonging to the same class. wolffd@0: % wolffd@0: % Function has two syntaxes: wolffd@0: % wolffd@0: % * If first argument gives the map topology, i.e. is map or topol struct wolffd@0: % or cell indicating the topology, the initial color coding of the wolffd@0: % units may be given by a string ('rgb1','rgb2','rgb3','rgb4', or 'hsv') wolffd@0: % which describe a predefined coloring scheme. (see SOM_COLORCODE). wolffd@0: % or an initial color matrix of size Mx3 with RGB triplets as rows. wolffd@0: % * Another possibility is to give just the classification vector wolffd@0: % of size Mx1 and an initial color matrix of size Mx3 with RGB wolffd@0: % triplets as rows. wolffd@0: % wolffd@0: % EXAMPLE (requires Matlab Statistics Toolbox) wolffd@0: % wolffd@0: % % Do a 10-cluster single linkage hierachical clustering for SOM units wolffd@0: % class=cluster(linkage(pdist(sM.codebook),'single'),10); wolffd@0: % % Color code the clusters wolffd@0: % C=som_clustercolor(sM, class, 'rgb2'); wolffd@0: % % Visualize wolffd@0: % som_show(sM,'color',C); wolffd@0: % wolffd@0: % See also SOM_COLORCODE, SOM_KMEANSCOLOR, SOM_CPLANE, SOM_SHOW wolffd@0: wolffd@0: % Contributed to SOM Toolbox 2.0, February 11th, 2000 by Johan Himberg wolffd@0: % Copyright (c) by Johan Himberg wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta Johan 100200 wolffd@0: wolffd@0: %%% Check arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: error(nargchk(2, 3, nargin)); % check no. of input args is correct wolffd@0: wolffd@0: % Check 1s argument wolffd@0: wolffd@0: % Class matrix? wolffd@0: if vis_valuetype(m, {'nxm'}); wolffd@0: colorcode=class; wolffd@0: class=m; wolffd@0: if ~vis_valuetype(colorcode,{'nx3rgb',[size(class,1) 3]},'all'), wolffd@0: error(['If map or topol is not specified the colorcode must be a' ... wolffd@0: ' [size(class,1) 3] sized RGB matrix.']); wolffd@0: end wolffd@0: else wolffd@0: [tmp,ok,tmp]=som_set(m); wolffd@0: if isstruct(m) & all(ok) wolffd@0: switch m.type wolffd@0: case 'som_topol' % topol? wolffd@0: msize=m.msize; wolffd@0: lattice=m.lattice; wolffd@0: case 'som_map' wolffd@0: msize=m.topol.msize; % map? wolffd@0: lattice=m.topol.lattice; wolffd@0: otherwise wolffd@0: error('Invalid map or topol struct.'); wolffd@0: end wolffd@0: % cell? wolffd@0: elseif iscell(m) & vis_valuetype(size(m),{[1 2]}), wolffd@0: if vis_valuetype(m{2},{[1 2]}) & vis_valuetype(m{1},{'string'}), wolffd@0: lattice=m{1}; wolffd@0: msize=m{2}; wolffd@0: else wolffd@0: error('Invalid map size information.'); wolffd@0: end wolffd@0: else wolffd@0: % not known type wolffd@0: error('Invalid first argument!'); wolffd@0: end wolffd@0: % Check map parameters wolffd@0: switch lattice % lattice wolffd@0: case 'hexa' wolffd@0: ; wolffd@0: case 'rect' wolffd@0: ; wolffd@0: otherwise wolffd@0: error('Unknown lattice type'); wolffd@0: end wolffd@0: if length(msize)>2 % dimension wolffd@0: error('Only 2D maps allowed!'); wolffd@0: end wolffd@0: % Check colorcode wolffd@0: if nargin<3 | isempty(colorcode) wolffd@0: colorcode='rgb2'; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Check class wolffd@0: if any(class~=round(class)) wolffd@0: error('Class labels must be integer numbers.'); wolffd@0: end wolffd@0: wolffd@0: if min(class)<=0 wolffd@0: error('Class numbers should be greater than 0'); wolffd@0: end wolffd@0: wolffd@0: if ischar(colorcode), wolffd@0: switch colorcode wolffd@0: case{'rgb1','rgb2','rgb3','rgb4','hsv'} wolffd@0: colorcode=som_colorcode(m, colorcode); wolffd@0: otherwise wolffd@0: error(['Color code not known: should be ''rgb1'',''rgb2'',' ... wolffd@0: ' ''rgb3'',''rgb4'' or ''hsv''.']); wolffd@0: end wolffd@0: elseif ~vis_valuetype(colorcode,{'nx3rgb',[size(class,1) 3]},'all'); wolffd@0: error(['Invalid colorcode matrix: should be a ' ... wolffd@0: '[length(class) 3] sized RGB matrix.']); wolffd@0: end wolffd@0: wolffd@0: %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: % Go through all i classifications (columns) wolffd@0: for i=1:size(class,2), wolffd@0: % Get unique class labels in ith classification wolffd@0: c=unique(class(:,i))'; % row vector for loop indexing wolffd@0: % Go through all class in ith classification wolffd@0: for j=c; wolffd@0: index=(class(:,i)==j); wolffd@0: N=sum(index); wolffd@0: colors=colorcode(index,:); wolffd@0: % Calculate the mean color wolffd@0: meancolor=repmat(mean(colors,1),N,1); wolffd@0: % Select the original color that is closest to this mean wolffd@0: dist=sum((meancolor-colors).^2,2); wolffd@0: [tmp,min_dist_index]=min(dist); wolffd@0: best_color=repmat(colors(min_dist_index,:),N,1); wolffd@0: % Set the color to output variable wolffd@0: color(index,:,i)=best_color; wolffd@0: end wolffd@0: end