Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_dendrogram.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/som_dendrogram.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,292 @@ +function [h,Coord,Color,height] = som_dendrogram(Z,varargin) + +%SOM_DENDROGRAM Visualize a dendrogram. +% +% [h,Coord,Color,height] = som_dendrogram(Z, [[argID,] value, ...]) +% +% Z = som_linkage(sM); +% som_dendrogram(Z); +% som_dendrogram(Z,sM); +% som_dendrogram(Z,'coord',co); +% +% Input and output arguments ([]'s are optional): +% h (vector) handle to the arc lines +% Z (matrix) size n-1 x 1, the hierarchical cluster matrix +% returned by functions like LINKAGE and SOM_LINKAGE +% n is the number of original data samples. +% [argID, (string) See below. The values which are unambiguous can +% value] (varies) be given without the preceeding argID. +% Coord (matrix) size 2*n-1 x {1,2}, the coordinates of the +% original data samples and cluster nodes used +% in the visualization +% Color (matrix) size 2*n-1 x 3, the colors of ... +% height (vector) size 2*n-1 x 1, the heights of ... +% +% Here are the valid argument IDs and corresponding values. The values +% which are unambiguous (marked with '*') can be given without the +% preceeding argID. +% 'data' *(struct) map or data struct: many other optional +% arguments require this +% (matrix) data matrix +% 'coord' (matrix) size n x 1 or n x 2, the coordinates of +% the original data samples either in 1D or 2D +% (matrix) size 2*n-1 x {1,2}, the coordinates of both +% original data samples and each cluster +% *(string) 'SOM', 'pca#', 'sammon#', or 'cca#': the coordinates +% are calculated using the given data and the +% required projection algorithm. The '#' at the +% end of projection algorithms refers to the +% desired output dimension and can be either 1 or 2 +% (2 by default). In case of 'SOM', the unit +% coordinates (given by SOM_VIS_COORDS) are used. +% 'color' (matrix) size n x 3, the color of the original data samples +% (matrix) size 2*n-1 x 3, the colors of both original +% data samples and each cluster +% (string) color specification, e.g. 'r.', used for each node +% 'height' (vector) size n-1 x 1, the heights used for each cluster +% (vector) size 2*n-1 x 1, the heights used for both original +% data samples and each cluster +% *(string) 'order', the order of combination determines height +% 'depth', the depth at which the combination +% happens determines height +% 'linecolor' (string) color specification for the arc color, 'k' by default +% (vector) size 1 x 3 +% +% See also SOM_LINKAGE, DENDROGRAM. + +% Copyright (c) 2000 by Juha Vesanto +% Contributed to SOM Toolbox on June 16th, 2000 by Juha Vesanto +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 2.0beta juuso 160600 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% read the arguments + +% Z +nd = size(Z,1)+1; +nc = size(Z,1); + +% varargin +Coordtype = 'natural'; Coord = []; codim = 1; +Colortype = 'none'; Color = []; +height = [zeros(nd,1); Z(:,3)]; +M = []; +linecol = 'k'; + +i=1; +while i<=length(varargin), + argok = 1; + if ischar(varargin{i}), + switch varargin{i}, + case 'data', i = i + 1; M = varargin{i}; + case 'coord', + i=i+1; + if isnumeric(varargin{i}), Coord = varargin{i}; Coordtype = 'given'; + else + if strcmp(varargin{i},'SOM'), Coordtype = 'SOM'; + else Coordtype = 'projection'; Coord = varargin{i}; + end + end + case 'color', + i=i+1; + if isempty(varargin{i}), Colortype = 'none'; + elseif ischar(varargin{i}), Colortype = 'colorspec'; Color = varargin{i}; + else Colortype = 'given'; Color = varargin{i}; + end + case 'height', i=i+1; height = varargin{i}; + case 'linecolor', i=i+1; linecol = varargin{i}; + case 'SOM', + Coordtype = 'SOM'; + case {'pca','pca1','pca2','sammon','sammon1','sammon2','cca','cca1','cca2'}, + Coordtype = 'projection'; Coord = varargin{i}; + case {'order','depth'}, height = varargin{i}; + end + elseif isstruct(varargin{i}), M = varargin{i}; + else + argok = 0; + end + if ~argok, + disp(['(som_dendrogram) Ignoring invalid argument #' num2str(i+1)]); + end + i = i+1; +end + +switch Coordtype, + case 'SOM', + if isempty(M) | ~any(strcmp(M.type,{'som_map','som_topol'})) , + error('Cannot determine SOM coordinates without a SOM.'); + end + if strcmp(M.type,'som_map'), M = M.topol; end + case 'projection', + if isempty(M), error('Cannot do projection without the data.'); end + if isstruct(M), + if strcmp(M.type,'som_data'), M = M.data; + elseif strcmp(M.type,'som_map'), M = M.codebook; + end + end + if size(M,1) ~= nd, + error('Given data must be equal in length to the number of original data samples.') + end + case 'given', + if size(Coord,1) ~= nd & size(Coord,1) ~= nd+nc, + error('Size of given coordinate matrix does not match the cluster hierarchy.'); + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% initialization + +% Coordinates +switch Coordtype, + case 'natural', o = leavesorder(Z)'; [dummy,Coord] = sort(o); codim = 1; + case 'SOM', Coord = som_vis_coords(M.lattice,M.msize); codim = 2; + case 'projection', + switch Coord, + case {'pca','pca2'}, Coord = pcaproj(M,2); codim = 2; + case 'pca1', Coord = pcaproj(M,1); codim = 1; + case {'cca','cca2'}, Coord = cca(M,2,20); codim = 2; + case 'cca1', Coord = cca(M,1,20); codim = 1; + case {'sammon','sammon2'}, Coord = sammon(M,2,50); codim = 2; + case 'sammon1', Coord = sammon(M,1,50); codim = 1; + end + case 'given', codim = min(size(Coord,2),2); % nill +end + +if size(Coord,1) == nd, + Coord = [Coord; zeros(nc,size(Coord,2))]; + for i=(nd+1):(nd+nc), + leaves = leafnodes(Z,i,nd); + if any(leaves), Coord(i,:) = mean(Coord(leaves,:),1); else Coord(i,:) = Inf; end + end +end + +% Colors +switch Colortype, + case 'colorspec', % nill + case 'none', Color = ''; + case 'given', + if size(Color,1) == nd, + Color = [Color; zeros(nc,3)]; + for i=(nd+1):(nd+nc), + leaves = leafnodes(Z,i,nd); + if any(leaves), Color(i,:) = mean(Color(leaves,:),1); + else Color(i,:) = 0.8; + end + end + end +end + +% height +if ischar(height), + switch height, + case 'order', height = [zeros(nd,1); [1:nc]']; + case 'depth', height = nodedepth(Z); height = max(height) - height; + end +else + if length(height)==nc, height = [zeros(nd,1); height]; end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% draw + +% the arcs +lfrom = []; lto = []; +for i=1:nd+nc, + if i<=nd, ch = []; + elseif ~isfinite(Z(i-nd,3)), ch = []; + else ch = Z(i-nd,1:2)'; + end + if any(ch), + lfrom = [lfrom; i*ones(length(ch),1)]; + lto = [lto; ch]; + end +end + +% the coordinates of the arcs +if codim == 1, + Lx = [Coord(lfrom), Coord(lto), Coord(lto)]; + Ly = [height(lfrom), height(lfrom), height(lto)]; + Lz = []; +else + Lx = [Coord(lfrom,1), Coord(lto,1), Coord(lto,1)]; + Ly = [Coord(lfrom,2), Coord(lto,2), Coord(lto,2)]; + Lz = [height(lfrom), height(lfrom), height(lto)]; +end + +washold = ishold; +if ~washold, cla; end + +% plot the lines +if isempty(Lz), + h = line(Lx',Ly','color',linecol); +else + h = line(Lx',Ly',Lz','color',linecol); + if ~washold, view(3); end + rotate3d on +end + +% plot the nodes +hold on +switch Colortype, + case 'none', % nill + case 'colorspec', + if codim == 1, plot(Coord,height,Color); + else plot3(Coord(:,1), Coord(:,2), height, Color); + end + case 'given', + som_grid('rect',[nd+nc 1],'line','none','Coord',[Coord, height],... + 'Markersize',10,'Markercolor',Color); +end +if ~washold, hold off, end + +return; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% subfunctions + +function depth = nodedepth(Z) + + nd = size(Z,1)+1; + nc = size(Z,1); + depth = zeros(nd+nc,1); + ch = nc+nd-1; + while any(ch), + c = ch(1); ch = ch(2:end); + if c>nd & isfinite(Z(c-nd,3)), + chc = Z(c-nd,1:2); + depth(chc) = depth(c) + 1; + ch = [ch, chc]; + end + end + return; + +function inds = leafnodes(Z,i,nd) + + inds = []; + ch = i; + while any(ch), + c = ch(1); ch = ch(2:end); + if c>nd & isfinite(Z(c-nd,3)), ch = [ch, Z(c-nd,1:2)]; end + if c<=nd, inds(end+1) = c; end + end + return; + +function order = leavesorder(Z) + + nd = size(Z,1)+1; + order = 2*nd-1; + nonleaves = 1; + while any(nonleaves), + j = nonleaves(1); + ch = Z(order(j)-nd,1:2); + if j==1, oleft = []; else oleft = order(1:(j-1)); end + if j==length(order), oright = []; else oright = order((j+1):length(order)); end + order = [oleft, ch, oright]; + nonleaves = find(order>nd); + end + return; + + + \ No newline at end of file