annotate 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
rev   line source
wolffd@0 1 function [h,Coord,Color,height] = som_dendrogram(Z,varargin)
wolffd@0 2
wolffd@0 3 %SOM_DENDROGRAM Visualize a dendrogram.
wolffd@0 4 %
wolffd@0 5 % [h,Coord,Color,height] = som_dendrogram(Z, [[argID,] value, ...])
wolffd@0 6 %
wolffd@0 7 % Z = som_linkage(sM);
wolffd@0 8 % som_dendrogram(Z);
wolffd@0 9 % som_dendrogram(Z,sM);
wolffd@0 10 % som_dendrogram(Z,'coord',co);
wolffd@0 11 %
wolffd@0 12 % Input and output arguments ([]'s are optional):
wolffd@0 13 % h (vector) handle to the arc lines
wolffd@0 14 % Z (matrix) size n-1 x 1, the hierarchical cluster matrix
wolffd@0 15 % returned by functions like LINKAGE and SOM_LINKAGE
wolffd@0 16 % n is the number of original data samples.
wolffd@0 17 % [argID, (string) See below. The values which are unambiguous can
wolffd@0 18 % value] (varies) be given without the preceeding argID.
wolffd@0 19 % Coord (matrix) size 2*n-1 x {1,2}, the coordinates of the
wolffd@0 20 % original data samples and cluster nodes used
wolffd@0 21 % in the visualization
wolffd@0 22 % Color (matrix) size 2*n-1 x 3, the colors of ...
wolffd@0 23 % height (vector) size 2*n-1 x 1, the heights of ...
wolffd@0 24 %
wolffd@0 25 % Here are the valid argument IDs and corresponding values. The values
wolffd@0 26 % which are unambiguous (marked with '*') can be given without the
wolffd@0 27 % preceeding argID.
wolffd@0 28 % 'data' *(struct) map or data struct: many other optional
wolffd@0 29 % arguments require this
wolffd@0 30 % (matrix) data matrix
wolffd@0 31 % 'coord' (matrix) size n x 1 or n x 2, the coordinates of
wolffd@0 32 % the original data samples either in 1D or 2D
wolffd@0 33 % (matrix) size 2*n-1 x {1,2}, the coordinates of both
wolffd@0 34 % original data samples and each cluster
wolffd@0 35 % *(string) 'SOM', 'pca#', 'sammon#', or 'cca#': the coordinates
wolffd@0 36 % are calculated using the given data and the
wolffd@0 37 % required projection algorithm. The '#' at the
wolffd@0 38 % end of projection algorithms refers to the
wolffd@0 39 % desired output dimension and can be either 1 or 2
wolffd@0 40 % (2 by default). In case of 'SOM', the unit
wolffd@0 41 % coordinates (given by SOM_VIS_COORDS) are used.
wolffd@0 42 % 'color' (matrix) size n x 3, the color of the original data samples
wolffd@0 43 % (matrix) size 2*n-1 x 3, the colors of both original
wolffd@0 44 % data samples and each cluster
wolffd@0 45 % (string) color specification, e.g. 'r.', used for each node
wolffd@0 46 % 'height' (vector) size n-1 x 1, the heights used for each cluster
wolffd@0 47 % (vector) size 2*n-1 x 1, the heights used for both original
wolffd@0 48 % data samples and each cluster
wolffd@0 49 % *(string) 'order', the order of combination determines height
wolffd@0 50 % 'depth', the depth at which the combination
wolffd@0 51 % happens determines height
wolffd@0 52 % 'linecolor' (string) color specification for the arc color, 'k' by default
wolffd@0 53 % (vector) size 1 x 3
wolffd@0 54 %
wolffd@0 55 % See also SOM_LINKAGE, DENDROGRAM.
wolffd@0 56
wolffd@0 57 % Copyright (c) 2000 by Juha Vesanto
wolffd@0 58 % Contributed to SOM Toolbox on June 16th, 2000 by Juha Vesanto
wolffd@0 59 % http://www.cis.hut.fi/projects/somtoolbox/
wolffd@0 60
wolffd@0 61 % Version 2.0beta juuso 160600
wolffd@0 62
wolffd@0 63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 64 %% read the arguments
wolffd@0 65
wolffd@0 66 % Z
wolffd@0 67 nd = size(Z,1)+1;
wolffd@0 68 nc = size(Z,1);
wolffd@0 69
wolffd@0 70 % varargin
wolffd@0 71 Coordtype = 'natural'; Coord = []; codim = 1;
wolffd@0 72 Colortype = 'none'; Color = [];
wolffd@0 73 height = [zeros(nd,1); Z(:,3)];
wolffd@0 74 M = [];
wolffd@0 75 linecol = 'k';
wolffd@0 76
wolffd@0 77 i=1;
wolffd@0 78 while i<=length(varargin),
wolffd@0 79 argok = 1;
wolffd@0 80 if ischar(varargin{i}),
wolffd@0 81 switch varargin{i},
wolffd@0 82 case 'data', i = i + 1; M = varargin{i};
wolffd@0 83 case 'coord',
wolffd@0 84 i=i+1;
wolffd@0 85 if isnumeric(varargin{i}), Coord = varargin{i}; Coordtype = 'given';
wolffd@0 86 else
wolffd@0 87 if strcmp(varargin{i},'SOM'), Coordtype = 'SOM';
wolffd@0 88 else Coordtype = 'projection'; Coord = varargin{i};
wolffd@0 89 end
wolffd@0 90 end
wolffd@0 91 case 'color',
wolffd@0 92 i=i+1;
wolffd@0 93 if isempty(varargin{i}), Colortype = 'none';
wolffd@0 94 elseif ischar(varargin{i}), Colortype = 'colorspec'; Color = varargin{i};
wolffd@0 95 else Colortype = 'given'; Color = varargin{i};
wolffd@0 96 end
wolffd@0 97 case 'height', i=i+1; height = varargin{i};
wolffd@0 98 case 'linecolor', i=i+1; linecol = varargin{i};
wolffd@0 99 case 'SOM',
wolffd@0 100 Coordtype = 'SOM';
wolffd@0 101 case {'pca','pca1','pca2','sammon','sammon1','sammon2','cca','cca1','cca2'},
wolffd@0 102 Coordtype = 'projection'; Coord = varargin{i};
wolffd@0 103 case {'order','depth'}, height = varargin{i};
wolffd@0 104 end
wolffd@0 105 elseif isstruct(varargin{i}), M = varargin{i};
wolffd@0 106 else
wolffd@0 107 argok = 0;
wolffd@0 108 end
wolffd@0 109 if ~argok,
wolffd@0 110 disp(['(som_dendrogram) Ignoring invalid argument #' num2str(i+1)]);
wolffd@0 111 end
wolffd@0 112 i = i+1;
wolffd@0 113 end
wolffd@0 114
wolffd@0 115 switch Coordtype,
wolffd@0 116 case 'SOM',
wolffd@0 117 if isempty(M) | ~any(strcmp(M.type,{'som_map','som_topol'})) ,
wolffd@0 118 error('Cannot determine SOM coordinates without a SOM.');
wolffd@0 119 end
wolffd@0 120 if strcmp(M.type,'som_map'), M = M.topol; end
wolffd@0 121 case 'projection',
wolffd@0 122 if isempty(M), error('Cannot do projection without the data.'); end
wolffd@0 123 if isstruct(M),
wolffd@0 124 if strcmp(M.type,'som_data'), M = M.data;
wolffd@0 125 elseif strcmp(M.type,'som_map'), M = M.codebook;
wolffd@0 126 end
wolffd@0 127 end
wolffd@0 128 if size(M,1) ~= nd,
wolffd@0 129 error('Given data must be equal in length to the number of original data samples.')
wolffd@0 130 end
wolffd@0 131 case 'given',
wolffd@0 132 if size(Coord,1) ~= nd & size(Coord,1) ~= nd+nc,
wolffd@0 133 error('Size of given coordinate matrix does not match the cluster hierarchy.');
wolffd@0 134 end
wolffd@0 135 end
wolffd@0 136
wolffd@0 137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 138 %% initialization
wolffd@0 139
wolffd@0 140 % Coordinates
wolffd@0 141 switch Coordtype,
wolffd@0 142 case 'natural', o = leavesorder(Z)'; [dummy,Coord] = sort(o); codim = 1;
wolffd@0 143 case 'SOM', Coord = som_vis_coords(M.lattice,M.msize); codim = 2;
wolffd@0 144 case 'projection',
wolffd@0 145 switch Coord,
wolffd@0 146 case {'pca','pca2'}, Coord = pcaproj(M,2); codim = 2;
wolffd@0 147 case 'pca1', Coord = pcaproj(M,1); codim = 1;
wolffd@0 148 case {'cca','cca2'}, Coord = cca(M,2,20); codim = 2;
wolffd@0 149 case 'cca1', Coord = cca(M,1,20); codim = 1;
wolffd@0 150 case {'sammon','sammon2'}, Coord = sammon(M,2,50); codim = 2;
wolffd@0 151 case 'sammon1', Coord = sammon(M,1,50); codim = 1;
wolffd@0 152 end
wolffd@0 153 case 'given', codim = min(size(Coord,2),2); % nill
wolffd@0 154 end
wolffd@0 155
wolffd@0 156 if size(Coord,1) == nd,
wolffd@0 157 Coord = [Coord; zeros(nc,size(Coord,2))];
wolffd@0 158 for i=(nd+1):(nd+nc),
wolffd@0 159 leaves = leafnodes(Z,i,nd);
wolffd@0 160 if any(leaves), Coord(i,:) = mean(Coord(leaves,:),1); else Coord(i,:) = Inf; end
wolffd@0 161 end
wolffd@0 162 end
wolffd@0 163
wolffd@0 164 % Colors
wolffd@0 165 switch Colortype,
wolffd@0 166 case 'colorspec', % nill
wolffd@0 167 case 'none', Color = '';
wolffd@0 168 case 'given',
wolffd@0 169 if size(Color,1) == nd,
wolffd@0 170 Color = [Color; zeros(nc,3)];
wolffd@0 171 for i=(nd+1):(nd+nc),
wolffd@0 172 leaves = leafnodes(Z,i,nd);
wolffd@0 173 if any(leaves), Color(i,:) = mean(Color(leaves,:),1);
wolffd@0 174 else Color(i,:) = 0.8;
wolffd@0 175 end
wolffd@0 176 end
wolffd@0 177 end
wolffd@0 178 end
wolffd@0 179
wolffd@0 180 % height
wolffd@0 181 if ischar(height),
wolffd@0 182 switch height,
wolffd@0 183 case 'order', height = [zeros(nd,1); [1:nc]'];
wolffd@0 184 case 'depth', height = nodedepth(Z); height = max(height) - height;
wolffd@0 185 end
wolffd@0 186 else
wolffd@0 187 if length(height)==nc, height = [zeros(nd,1); height]; end
wolffd@0 188 end
wolffd@0 189
wolffd@0 190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 191 %% draw
wolffd@0 192
wolffd@0 193 % the arcs
wolffd@0 194 lfrom = []; lto = [];
wolffd@0 195 for i=1:nd+nc,
wolffd@0 196 if i<=nd, ch = [];
wolffd@0 197 elseif ~isfinite(Z(i-nd,3)), ch = [];
wolffd@0 198 else ch = Z(i-nd,1:2)';
wolffd@0 199 end
wolffd@0 200 if any(ch),
wolffd@0 201 lfrom = [lfrom; i*ones(length(ch),1)];
wolffd@0 202 lto = [lto; ch];
wolffd@0 203 end
wolffd@0 204 end
wolffd@0 205
wolffd@0 206 % the coordinates of the arcs
wolffd@0 207 if codim == 1,
wolffd@0 208 Lx = [Coord(lfrom), Coord(lto), Coord(lto)];
wolffd@0 209 Ly = [height(lfrom), height(lfrom), height(lto)];
wolffd@0 210 Lz = [];
wolffd@0 211 else
wolffd@0 212 Lx = [Coord(lfrom,1), Coord(lto,1), Coord(lto,1)];
wolffd@0 213 Ly = [Coord(lfrom,2), Coord(lto,2), Coord(lto,2)];
wolffd@0 214 Lz = [height(lfrom), height(lfrom), height(lto)];
wolffd@0 215 end
wolffd@0 216
wolffd@0 217 washold = ishold;
wolffd@0 218 if ~washold, cla; end
wolffd@0 219
wolffd@0 220 % plot the lines
wolffd@0 221 if isempty(Lz),
wolffd@0 222 h = line(Lx',Ly','color',linecol);
wolffd@0 223 else
wolffd@0 224 h = line(Lx',Ly',Lz','color',linecol);
wolffd@0 225 if ~washold, view(3); end
wolffd@0 226 rotate3d on
wolffd@0 227 end
wolffd@0 228
wolffd@0 229 % plot the nodes
wolffd@0 230 hold on
wolffd@0 231 switch Colortype,
wolffd@0 232 case 'none', % nill
wolffd@0 233 case 'colorspec',
wolffd@0 234 if codim == 1, plot(Coord,height,Color);
wolffd@0 235 else plot3(Coord(:,1), Coord(:,2), height, Color);
wolffd@0 236 end
wolffd@0 237 case 'given',
wolffd@0 238 som_grid('rect',[nd+nc 1],'line','none','Coord',[Coord, height],...
wolffd@0 239 'Markersize',10,'Markercolor',Color);
wolffd@0 240 end
wolffd@0 241 if ~washold, hold off, end
wolffd@0 242
wolffd@0 243 return;
wolffd@0 244
wolffd@0 245
wolffd@0 246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 247 %% subfunctions
wolffd@0 248
wolffd@0 249 function depth = nodedepth(Z)
wolffd@0 250
wolffd@0 251 nd = size(Z,1)+1;
wolffd@0 252 nc = size(Z,1);
wolffd@0 253 depth = zeros(nd+nc,1);
wolffd@0 254 ch = nc+nd-1;
wolffd@0 255 while any(ch),
wolffd@0 256 c = ch(1); ch = ch(2:end);
wolffd@0 257 if c>nd & isfinite(Z(c-nd,3)),
wolffd@0 258 chc = Z(c-nd,1:2);
wolffd@0 259 depth(chc) = depth(c) + 1;
wolffd@0 260 ch = [ch, chc];
wolffd@0 261 end
wolffd@0 262 end
wolffd@0 263 return;
wolffd@0 264
wolffd@0 265 function inds = leafnodes(Z,i,nd)
wolffd@0 266
wolffd@0 267 inds = [];
wolffd@0 268 ch = i;
wolffd@0 269 while any(ch),
wolffd@0 270 c = ch(1); ch = ch(2:end);
wolffd@0 271 if c>nd & isfinite(Z(c-nd,3)), ch = [ch, Z(c-nd,1:2)]; end
wolffd@0 272 if c<=nd, inds(end+1) = c; end
wolffd@0 273 end
wolffd@0 274 return;
wolffd@0 275
wolffd@0 276 function order = leavesorder(Z)
wolffd@0 277
wolffd@0 278 nd = size(Z,1)+1;
wolffd@0 279 order = 2*nd-1;
wolffd@0 280 nonleaves = 1;
wolffd@0 281 while any(nonleaves),
wolffd@0 282 j = nonleaves(1);
wolffd@0 283 ch = Z(order(j)-nd,1:2);
wolffd@0 284 if j==1, oleft = []; else oleft = order(1:(j-1)); end
wolffd@0 285 if j==length(order), oright = []; else oright = order((j+1):length(order)); end
wolffd@0 286 order = [oleft, ch, oright];
wolffd@0 287 nonleaves = find(order>nd);
wolffd@0 288 end
wolffd@0 289 return;
wolffd@0 290
wolffd@0 291
wolffd@0 292