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