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