wolffd@0
|
1 function colors=som_colorcode(m, colorcode, scaling)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_COLORCODE Calculates a heuristic color coding for the SOM grid
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % colors = som_colorcode(m, colorcode, scaling)
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
8 % m (struct) map or topol struct
|
wolffd@0
|
9 % (cell array) of form {str,[m1 m2]} where
|
wolffd@0
|
10 % str = 'hexa' or 'rect' and [m1 m2] = msize
|
wolffd@0
|
11 % (matrix) size N x 2, unit coordinates
|
wolffd@0
|
12 % [colorcode] (string) 'rgb1' (default),'rgb2','rgb3','rgb4','hsv'
|
wolffd@0
|
13 % [scaling] (scalar) 1=on (default), 0=off. Has effect only
|
wolffd@0
|
14 % if m is a Nx2 matrix of coordinates:
|
wolffd@0
|
15 % controls whether these are scaled to
|
wolffd@0
|
16 % range [0,1] or not.
|
wolffd@0
|
17 %
|
wolffd@0
|
18 % colors (matrix) size N x 3, RGB colors for each unit (or point)
|
wolffd@0
|
19 %
|
wolffd@0
|
20 % The function gives a color coding by location for the map grid
|
wolffd@0
|
21 % (or arbitrary set of points). Map grid coordinates are always linearly
|
wolffd@0
|
22 % normalized to a unit square (x and y coordinates between [0,1]), except
|
wolffd@0
|
23 % if m is a Nx2 matrix and scaling=0. In that case too, the coordinates
|
wolffd@0
|
24 % must be in range [0,1].
|
wolffd@0
|
25 %
|
wolffd@0
|
26 % Following heuristic color codings are available:
|
wolffd@0
|
27 %
|
wolffd@0
|
28 % 'rgb1' slice of RGB-cube so that green - yellow
|
wolffd@0
|
29 % the corners have colors: | |
|
wolffd@0
|
30 % blue - magenta
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % 'rgb2' slice of RGB-cube so that red - yellow
|
wolffd@0
|
33 % the corners have colors: | |
|
wolffd@0
|
34 % blue - cyan
|
wolffd@0
|
35 %
|
wolffd@0
|
36 % 'rgb3' slice of RGB-cube so that mixed_green - orange
|
wolffd@0
|
37 % the corners have colors: | |
|
wolffd@0
|
38 % light_blue - pink
|
wolffd@0
|
39 %
|
wolffd@0
|
40 % 'rgb4' has 'rgb1' on the diagonal + additional colors in corners
|
wolffd@0
|
41 % (more resolution but visually strongly discontinuous)
|
wolffd@0
|
42 %
|
wolffd@0
|
43 % 'hsv' angle and radius from map centre are coded by hue and
|
wolffd@0
|
44 % intensity (more resoluton but visually discontinuous)
|
wolffd@0
|
45 %
|
wolffd@0
|
46 % See also SOM_CPLANE, SOM_SHOW, SOM_CLUSTERCOLOR, SOM_KMEANSCOLOR,
|
wolffd@0
|
47 % SOM_BMUCOLOR.
|
wolffd@0
|
48
|
wolffd@0
|
49 % Contributed to SOM Toolbox 2.0, February 11th, 2000 by Johan Himberg
|
wolffd@0
|
50 % Copyright (c) by Johan Himberg
|
wolffd@0
|
51 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
52
|
wolffd@0
|
53 % Version 2.0 Johan 140799
|
wolffd@0
|
54
|
wolffd@0
|
55 %%% Check arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
56
|
wolffd@0
|
57 error(nargchk(1, 3, nargin)); % check no. of input args is correct
|
wolffd@0
|
58
|
wolffd@0
|
59 %% Check m: map, topol, cell or data?
|
wolffd@0
|
60
|
wolffd@0
|
61 if vis_valuetype(m,{'nx2'}),
|
wolffd@0
|
62 p=m; % explicit coordinates
|
wolffd@0
|
63
|
wolffd@0
|
64 else
|
wolffd@0
|
65
|
wolffd@0
|
66 % map, topol, cell
|
wolffd@0
|
67
|
wolffd@0
|
68 [tmp,ok,tmp]=som_set(m);
|
wolffd@0
|
69 if isstruct(m) & all(ok)
|
wolffd@0
|
70 switch m.type
|
wolffd@0
|
71 case 'som_topol' % topol
|
wolffd@0
|
72 msize=m.msize;
|
wolffd@0
|
73 lattice=m.lattice;
|
wolffd@0
|
74 case 'som_map'
|
wolffd@0
|
75 msize=m.topol.msize; % map
|
wolffd@0
|
76 lattice=m.topol.lattice;
|
wolffd@0
|
77 otherwise
|
wolffd@0
|
78 error('Invalid map or topol struct.');
|
wolffd@0
|
79 end
|
wolffd@0
|
80
|
wolffd@0
|
81 % cell
|
wolffd@0
|
82
|
wolffd@0
|
83 elseif iscell(m) & vis_valuetype(size(m),{[1 2]}),
|
wolffd@0
|
84 if vis_valuetype(m{2},{[1 2]}) & vis_valuetype(m{1},{'string'}),
|
wolffd@0
|
85 lattice=m{1};
|
wolffd@0
|
86 msize=m{2};
|
wolffd@0
|
87 else
|
wolffd@0
|
88 error('Invalid map size information.');
|
wolffd@0
|
89 end
|
wolffd@0
|
90 end
|
wolffd@0
|
91
|
wolffd@0
|
92 %% Check map parameters
|
wolffd@0
|
93
|
wolffd@0
|
94 switch lattice % lattice
|
wolffd@0
|
95 case 'hexa'
|
wolffd@0
|
96 ;
|
wolffd@0
|
97 case 'rect'
|
wolffd@0
|
98 ;
|
wolffd@0
|
99 otherwise
|
wolffd@0
|
100 error('Unknown lattice type');
|
wolffd@0
|
101 end
|
wolffd@0
|
102
|
wolffd@0
|
103 if length(msize)>2 % dimension
|
wolffd@0
|
104 error('Only 2D maps allowed!');
|
wolffd@0
|
105 end
|
wolffd@0
|
106
|
wolffd@0
|
107
|
wolffd@0
|
108 % Calculate coordinates
|
wolffd@0
|
109 p=som_unit_coords(msize,lattice,'sheet');
|
wolffd@0
|
110
|
wolffd@0
|
111 % Set scaling to 1 as it is done always in this case
|
wolffd@0
|
112 scaling=1;
|
wolffd@0
|
113 end
|
wolffd@0
|
114
|
wolffd@0
|
115 % Check colorcode
|
wolffd@0
|
116
|
wolffd@0
|
117 if nargin < 2 | isempty(colorcode),
|
wolffd@0
|
118 colorcode='rgb1';
|
wolffd@0
|
119 end
|
wolffd@0
|
120 if ~ischar(colorcode)
|
wolffd@0
|
121 error('String value for colorcode mode expected.');
|
wolffd@0
|
122 else
|
wolffd@0
|
123 switch colorcode
|
wolffd@0
|
124 case { 'rgb1', 'rgb2', 'rgb3' , 'rgb4' ,'hsv'}
|
wolffd@0
|
125 otherwise
|
wolffd@0
|
126 error([ 'Colorcode mode ' colorcode ' not implemented.']);
|
wolffd@0
|
127 end
|
wolffd@0
|
128 end
|
wolffd@0
|
129
|
wolffd@0
|
130 % Check scaling
|
wolffd@0
|
131
|
wolffd@0
|
132 if nargin < 3 | isempty(scaling)
|
wolffd@0
|
133 scaling=1;
|
wolffd@0
|
134 end
|
wolffd@0
|
135
|
wolffd@0
|
136 if ~vis_valuetype(scaling,{'1x1'})
|
wolffd@0
|
137 error('Scaling should be 0 (off) or 1 (on).');
|
wolffd@0
|
138 end
|
wolffd@0
|
139
|
wolffd@0
|
140 %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
141
|
wolffd@0
|
142 % scale coordintes between [0,1]
|
wolffd@0
|
143
|
wolffd@0
|
144 if scaling
|
wolffd@0
|
145 n=size(p,1);
|
wolffd@0
|
146 mn=min(p);
|
wolffd@0
|
147 e=max(p)-mn;
|
wolffd@0
|
148 p=(p-repmat(mn,n,1))./repmat(e,n,1);
|
wolffd@0
|
149 elseif sum(p(:,1)>1+p(:,1)<0+p(:,2)>1+p(:,2)<0),
|
wolffd@0
|
150 error('Coordinates out of range [0,1].');
|
wolffd@0
|
151 end
|
wolffd@0
|
152
|
wolffd@0
|
153 switch colorcode
|
wolffd@0
|
154 case 'rgb1'
|
wolffd@0
|
155 h(:,1)=p(:,1);
|
wolffd@0
|
156 h(:,2)=1-p(:,2);
|
wolffd@0
|
157 h(:,3)=p(:,2);
|
wolffd@0
|
158 case 'rgb2'
|
wolffd@0
|
159 h(:,1)=p(:,1);
|
wolffd@0
|
160 h(:,2)=1-p(:,2);
|
wolffd@0
|
161 h(:,3)=1-p(:,1);
|
wolffd@0
|
162 case 'rgb3'
|
wolffd@0
|
163 h(:,1)=p(:,1);
|
wolffd@0
|
164 h(:,2)=.5;
|
wolffd@0
|
165 h(:,3)=p(:,2);
|
wolffd@0
|
166 case 'rgb4'
|
wolffd@0
|
167 p=rgb4(p);
|
wolffd@0
|
168 h(:,1)=p(:,1);
|
wolffd@0
|
169 h(:,2)=1-p(:,2);
|
wolffd@0
|
170 h(:,3)=p(:,3);
|
wolffd@0
|
171 case 'hsv'
|
wolffd@0
|
172 munits = n;
|
wolffd@0
|
173 Hsv = zeros(munits,3);
|
wolffd@0
|
174 for i=1:n,
|
wolffd@0
|
175 dx = .5-p(i,1);
|
wolffd@0
|
176 dy = .5-p(i,2);
|
wolffd@0
|
177 r = sqrt(dx^2+dy^2);
|
wolffd@0
|
178 if r==0,
|
wolffd@0
|
179 h=1;
|
wolffd@0
|
180 elseif dx==0,
|
wolffd@0
|
181 h=.5; %h=ay;
|
wolffd@0
|
182 elseif dy==0,
|
wolffd@0
|
183 h=.5; %h=ax;
|
wolffd@0
|
184 else
|
wolffd@0
|
185 h = min(abs(.5/(dx/r)),abs(.5/(dy/r)));
|
wolffd@0
|
186 end
|
wolffd@0
|
187
|
wolffd@0
|
188 if r==0,
|
wolffd@0
|
189 angle = 0;
|
wolffd@0
|
190 else
|
wolffd@0
|
191 angle = acos(dx/r);
|
wolffd@0
|
192 if dy<0,
|
wolffd@0
|
193 angle = 2*pi-angle;
|
wolffd@0
|
194 end
|
wolffd@0
|
195 end
|
wolffd@0
|
196
|
wolffd@0
|
197 Hsv(i,1) = 1-sin(angle/4);
|
wolffd@0
|
198 Hsv(i,2) = 1;
|
wolffd@0
|
199 Hsv(i,3) = r/h;
|
wolffd@0
|
200 h = hsv2rgb(Hsv);
|
wolffd@0
|
201 end
|
wolffd@0
|
202 end
|
wolffd@0
|
203
|
wolffd@0
|
204
|
wolffd@0
|
205 %% Build output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
206
|
wolffd@0
|
207 colors=h;
|
wolffd@0
|
208
|
wolffd@0
|
209 %% Subfunctions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% juha %%%%
|
wolffd@0
|
210
|
wolffd@0
|
211 function p=rgb4(coord)
|
wolffd@0
|
212
|
wolffd@0
|
213 for i=1:size(coord,1);
|
wolffd@0
|
214 p(i,:)=get_coords(coord(i,:))';
|
wolffd@0
|
215 end
|
wolffd@0
|
216
|
wolffd@0
|
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
218
|
wolffd@0
|
219 function coords=get_coords(coords)
|
wolffd@0
|
220
|
wolffd@0
|
221 %GET_COORDS
|
wolffd@0
|
222 %
|
wolffd@0
|
223 % get_coords(coords)
|
wolffd@0
|
224 %
|
wolffd@0
|
225 % ARGUMENTS
|
wolffd@0
|
226 %
|
wolffd@0
|
227 % coords (1x2 or 2x1 vector) coords(1) is an x-coordinate and coords(2)
|
wolffd@0
|
228 % y-coordinate.
|
wolffd@0
|
229 %
|
wolffd@0
|
230 %
|
wolffd@0
|
231 % RETURNS
|
wolffd@0
|
232 %
|
wolffd@0
|
233 % coords (3x1 vector) x,y and z-coordinates.
|
wolffd@0
|
234 %
|
wolffd@0
|
235
|
wolffd@0
|
236 if ~(all(size(coords) == [1 2]) | all(size(coords) == [2 1]))
|
wolffd@0
|
237 error('Argument ''coords'' must be an 2x1 or 1x2 vector.');
|
wolffd@0
|
238 end
|
wolffd@0
|
239
|
wolffd@0
|
240 if all(size(coords) == [1 2])
|
wolffd@0
|
241 coords=coords';
|
wolffd@0
|
242 end
|
wolffd@0
|
243
|
wolffd@0
|
244 if any(coords > 1) any(coords < 0)
|
wolffd@0
|
245 error('Coordinates must lay inside the interval [0,1].');
|
wolffd@0
|
246 end
|
wolffd@0
|
247
|
wolffd@0
|
248 if coords(1) <= 1/(sqrt(2)+1),
|
wolffd@0
|
249 if coords(2) <= line3(coords(1))
|
wolffd@0
|
250 coords=coords_in_base(4,coords);
|
wolffd@0
|
251 elseif coords(2) <= line2(coords(1))
|
wolffd@0
|
252 coords=coords_in_base(1,coords);
|
wolffd@0
|
253 else
|
wolffd@0
|
254 coords=coords_in_base(2,coords);
|
wolffd@0
|
255 end
|
wolffd@0
|
256 elseif coords(1) <= sqrt(2)/(sqrt(2)+1)
|
wolffd@0
|
257 if coords(2) <= line1(coords(1))
|
wolffd@0
|
258 coords=coords_in_base(3,coords);
|
wolffd@0
|
259 elseif coords(2) <= line2(coords(1))
|
wolffd@0
|
260 coords=coords_in_base(1,coords);
|
wolffd@0
|
261 else
|
wolffd@0
|
262 coords=coords_in_base(2,coords);
|
wolffd@0
|
263 end
|
wolffd@0
|
264 else
|
wolffd@0
|
265 if coords(2) <= line1(coords(1)),
|
wolffd@0
|
266 coords=coords_in_base(3,coords);
|
wolffd@0
|
267 elseif coords(2) <= line4(coords(1))
|
wolffd@0
|
268 coords=coords_in_base(1,coords);
|
wolffd@0
|
269 else
|
wolffd@0
|
270 coords=coords_in_base(5,coords);
|
wolffd@0
|
271 end
|
wolffd@0
|
272 end
|
wolffd@0
|
273
|
wolffd@0
|
274
|
wolffd@0
|
275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
276
|
wolffd@0
|
277 function coords=coords_in_base(base_no,coords)
|
wolffd@0
|
278
|
wolffd@0
|
279 A=[0;1/(sqrt(2)+1)];
|
wolffd@0
|
280 E=[1;1];
|
wolffd@0
|
281 F=[0;0];
|
wolffd@0
|
282 G=[1;0];
|
wolffd@0
|
283 H=[0;1];
|
wolffd@0
|
284
|
wolffd@0
|
285 const=1+1/sqrt(2);
|
wolffd@0
|
286
|
wolffd@0
|
287 switch base_no
|
wolffd@0
|
288 case 1
|
wolffd@0
|
289 x=(coords-A)*const;
|
wolffd@0
|
290 coords=[(1/sqrt(2))*(x(1)-x(2));0.5*(x(1)+x(2));0.5*(x(1)+x(2))];
|
wolffd@0
|
291 case 2
|
wolffd@0
|
292 x=(coords-H)*const;
|
wolffd@0
|
293 coords=[0;x(1);1+x(2)];
|
wolffd@0
|
294 case 3
|
wolffd@0
|
295 x=(coords-G)*const;
|
wolffd@0
|
296 coords=[1;1+x(1);x(2)];
|
wolffd@0
|
297 case 4
|
wolffd@0
|
298 x=(coords-F)*const;
|
wolffd@0
|
299 coords=[0.5+(1/sqrt(2))*(x(1)-x(2));...
|
wolffd@0
|
300 0.5-(1/sqrt(2))*(x(1)+x(2));...
|
wolffd@0
|
301 0];
|
wolffd@0
|
302 case 5
|
wolffd@0
|
303 x=(coords-E)*const;
|
wolffd@0
|
304 coords=[0.5+(1/sqrt(2))*(x(1)-x(2));...
|
wolffd@0
|
305 0.5-(1/sqrt(2))*(x(1)+x(2));...
|
wolffd@0
|
306 1];
|
wolffd@0
|
307 end
|
wolffd@0
|
308
|
wolffd@0
|
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
310
|
wolffd@0
|
311 function y=line1(x)
|
wolffd@0
|
312
|
wolffd@0
|
313 y = x-1/(sqrt(2)+1);
|
wolffd@0
|
314
|
wolffd@0
|
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
316
|
wolffd@0
|
317 function y=line2(x)
|
wolffd@0
|
318
|
wolffd@0
|
319 y = x+1/(sqrt(2)+1);
|
wolffd@0
|
320
|
wolffd@0
|
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
322
|
wolffd@0
|
323 function y=line3(x)
|
wolffd@0
|
324
|
wolffd@0
|
325 y = -x+1/(sqrt(2)+1);
|
wolffd@0
|
326
|
wolffd@0
|
327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
328
|
wolffd@0
|
329 function y= line4(x)
|
wolffd@0
|
330
|
wolffd@0
|
331 y = -x+(2*sqrt(2)+1)/(sqrt(2)+1);
|
wolffd@0
|
332
|
wolffd@0
|
333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|