wolffd@0: function h = som_barplane(varargin) wolffd@0: wolffd@0: %SOM_BARPLANE Visualize the map prototype vectors as bar charts wolffd@0: % wolffd@0: % h = som_barplane(lattice, msize, data, [color], [scaling], [gap], [pos]) wolffd@0: % h = som_barplane(topol, data, [color], [scaling], [gap], [pos]) wolffd@0: % wolffd@0: % som_barplane('hexa',[5 5], rand(25,4), jet(4)) wolffd@0: % som_barplane(sM, sM.codebook,'none') wolffd@0: % wolffd@0: % Input and output argumetns ([]'s are optional): wolffd@0: % lattice (string) grid 'hexa' or 'rect' wolffd@0: % msize (vector) size 1x2, defines the map grid size msize, M=prod(msize) wolffd@0: % (matrix) size Mx2, gives explicit coordinates for each node: wolffd@0: % in this case the first argument does not matter. wolffd@0: % topol (struct) map or topology struct wolffd@0: % data (matrix) size Mxd, each row defines heights of the bars wolffd@0: % [color] (matrix) size dx3, of RGB triples. The rows define colors wolffd@0: % for each bar in a node. Default is hsv(d). A ColorSpec or wolffd@0: % (string) A ColorSpec or 'none' gives each bar the same color. wolffd@0: % [scaling] (string) 'none', 'unitwise' or 'varwise'. The scaling wolffd@0: % mode for the values. Default is 'varwise'. wolffd@0: % [gap] (scalar) Defines the gap between bars, limits: 0 <= gap <= 1 wolffd@0: % where 0=no gap, 1=bars are thin lines. Default is 0.25. wolffd@0: % [pos] (vector) 1x2 vector defines the position of origin. wolffd@0: % Default is [1 1]. wolffd@0: % wolffd@0: % h (scalar) the object handle to the PATCH object wolffd@0: % wolffd@0: % Axis are set as in SOM_CPLANE. wolffd@0: % wolffd@0: % For more help, try 'type som_barplane' or check out online documentation. wolffd@0: % See also SOM_CPLANE, SOM_PLOTPLANE, SOM_PIEPLANE. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_barplane wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Visualizes the map prototype vectors as bar charts. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % h = som_barplane(topol, data) wolffd@0: % h = som_barplane(lattice, msize, data) wolffd@0: % h = som_barplane(..., color) wolffd@0: % h = som_barplane(..., color, scaling) wolffd@0: % h = som_barplane(..., color, scaling, gap) wolffd@0: % h = som_barplane(..., color, scaling, gap, pos) wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % Visualizes the map prototype vectors as bar charts. wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % lattice The basic shape of the map units wolffd@0: % (string) 'hexa' or 'rect' positions the bar charts according to wolffd@0: % hexagonal or rectangular map lattice wolffd@0: % wolffd@0: % msize The size of the map grid wolffd@0: % (vector) [n1 n2] vector defines the map size (height: n1 units widht: n2 wolffd@0: % units, total: M=n1xn2 units). The units will be placed to their wolffd@0: % topological locations in order to form a uniform hexagonal or wolffd@0: % rectangular grid. wolffd@0: % (matrix) Mx2 matrix defines arbitary coordinates for the N units. In wolffd@0: % this case the argument 'lattice' has no effect wolffd@0: % wolffd@0: % topol Topology of the map grid wolffd@0: % wolffd@0: % (struct) map or topology struct from which the topology is taken wolffd@0: % wolffd@0: % data The data to use when constructing the bar charts. wolffd@0: % Typically, the map codebook or some of its components. wolffd@0: % (matrix) Mxd matrix. A row defines heights of the bars. wolffd@0: % wolffd@0: % OPTIONAL INPUT ARGUMENTS wolffd@0: % wolffd@0: % Note: if unspecified or given an empty value ('' or []), default wolffd@0: % values are used for optional input arguments. wolffd@0: % wolffd@0: % color The color of the bars in each pie wolffd@0: % (ColorSpec) or (string) 'none' gives the same color for each slice. wolffd@0: % (matrix) dx3 matrix assigns an RGB color determined by the dth row of wolffd@0: % the matrix to the dth bar (variable) in each bar plot. wolffd@0: % Default value is hsv(d). wolffd@0: % wolffd@0: % scaling How to scale the values wolffd@0: % (string) 'none', 'unitwise' or 'varwise'. This determines the wolffd@0: % scaling of codebook values when drawing the bars. wolffd@0: % wolffd@0: % 'none' don't scale at all. The bars are not limited wolffd@0: % to remain inside he units' area: That is, if value of wolffd@0: % some variable exceeds [-.625,.625] for 'rect' (and wolffd@0: % in "worst case" [-.5,-.5] for 'hexa') the bars may wolffd@0: % overlap other units. wolffd@0: % wolffd@0: % Base line (zero value line) wolffd@0: % - is in the middle of the unit if data (codebook) contains both wolffd@0: % negative and positive values (or is completely zero). wolffd@0: % - is in the top the unit if data (codebook) contains only wolffd@0: % non-positive values (everything <=0). wolffd@0: % - is in the bottom the unit if data (codebook) contains only wolffd@0: % non-negative values (everything >=0). wolffd@0: % wolffd@0: % 'varwise' scales values so that each variable is scaled separately wolffd@0: % so that when it gets its overall maximum value, the wolffd@0: % corresponding bar gets maximum range and for minimum value wolffd@0: % it gets the minimum range. Baseline: see scaling 'none' wolffd@0: % This is the default. wolffd@0: % wolffd@0: % 'unitwise' scales values in each unit individually so that the wolffd@0: % bars for variables having minimum and maximum values have minimum wolffd@0: % and maximum range inside each unit, respectively. wolffd@0: % In this case the zero value line may move depending on the values. wolffd@0: % wolffd@0: wolffd@0: % gap The gap between bars wolffd@0: % (scalar) 0: no gap: bars are glued together wolffd@0: % ... default value is 0.25 wolffd@0: % 1: maximum gap: bars are thin lines wolffd@0: % wolffd@0: % pos Position of origin wolffd@0: % (vector) size 1x2. This is meant for drawing the plane in arbitrary wolffd@0: % location in a figure. Note the operation: if this argument is wolffd@0: % given, the axis limits setting part in the routine is skipped and wolffd@0: % the limits setting will be left to be done by MATLAB's defaults. wolffd@0: % Default is [1 1]. wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % h (scalar) handle to the created patch object wolffd@0: % wolffd@0: % OBJECT TAGS wolffd@0: % wolffd@0: % One object handle is returned: field Tag is set to 'planeBar' wolffd@0: % wolffd@0: % FEATURES wolffd@0: % wolffd@0: % - The colors are fixed: changing colormap in the figure (see help wolffd@0: % colormap) will not change the coloring of the bars. wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % %%% Create the data and make a map wolffd@0: % wolffd@0: % data=rand(100,5); map=som_make(data); wolffd@0: % wolffd@0: % %%% Create a 'jet' colormap that has as many rows as the data has variables wolffd@0: % wolffd@0: % colors=jet(5); wolffd@0: % wolffd@0: % %%% Draw bars wolffd@0: % wolffd@0: % som_barplane(map.topol.lattice, map.topol.msize, map.codebook, colors); wolffd@0: % or som_barplane(map.topol, map.codebook, colors); wolffd@0: % or som_barplane(map, map.codebook, colors); wolffd@0: % wolffd@0: % %%% Draw the bars so that the gap between the bars is bigger and all wolffd@0: % bars are black wolffd@0: % wolffd@0: % som_barplane(map, map.codebook, 'k', '', 0.6); wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_cplane Visualize a 2D component plane, u-matrix or color plane wolffd@0: % som_plotplane Visualize the map prototype vectors as line graphs wolffd@0: % som_pieplane Visualize the map prototype vectors as pie charts wolffd@0: wolffd@0: % Copyright (c) 1999-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta Juha P 110599, Johan 140799, juuso 151199 140300 070600 wolffd@0: wolffd@0: %%% Check & Init arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: [nargin, lattice, msize, data, color, scaling, gap, pos] = vis_planeGetArgs(varargin{:}); wolffd@0: error(nargchk(3, 7, nargin)) % check that no. of input args is correct wolffd@0: wolffd@0: % Check pos wolffd@0: wolffd@0: if nargin < 7 | isempty(pos) wolffd@0: pos=NaN; % default value for pos (no translation) wolffd@0: elseif ~vis_valuetype(pos,{'1x2'}) wolffd@0: error('Position of origin has to be given as an 1x2 vector'); wolffd@0: end wolffd@0: wolffd@0: % Check gap wolffd@0: wolffd@0: if nargin < 6 | isempty(gap), wolffd@0: gap=0.25; % default value for gap wolffd@0: elseif ~vis_valuetype(gap, {'1x1'}), wolffd@0: error('Gap value must be scalar.'); wolffd@0: elseif ~(gap >= 0 & gap<=1) wolffd@0: error('Gap value must be in interval [0,1].') wolffd@0: end wolffd@0: wolffd@0: % Check scaling wolffd@0: wolffd@0: if nargin < 5 | isempty(scaling), wolffd@0: scaling='varwise'; wolffd@0: elseif ~vis_valuetype(scaling,{'string'}) | ... wolffd@0: ~any(strcmp(scaling,{'none','unitwise','varwise'})), wolffd@0: error('scaling sholud be ''none'', ''unitwise'' or ''varwise''.'); wolffd@0: end wolffd@0: wolffd@0: % Check msize wolffd@0: wolffd@0: if ~vis_valuetype(msize,{'1x2','nx2'}), wolffd@0: error('msize has to be 1x2 grid size vector or a Nx2 coordinate matrix.'); wolffd@0: end wolffd@0: wolffd@0: % Check data wolffd@0: wolffd@0: if ~isnumeric(data), wolffd@0: error('Data matrix has to be numeric.'); wolffd@0: elseif length(size((data)))>2 wolffd@0: error('Data matrix has too many dimensions!'); wolffd@0: else wolffd@0: d=size(data,2); wolffd@0: N=size(data,1); wolffd@0: end wolffd@0: wolffd@0: s=.8; % patch size scaling factor wolffd@0: wolffd@0: switch scaling, wolffd@0: case 'none' wolffd@0: % no scaling: don't scale wolffd@0: % Check data max and min values wolffd@0: positive=any(data(:)>0); negative=any(data(:)<0); wolffd@0: if (positive & negative) | (~positive & ~negative), wolffd@0: % Data contains both negative and positive values (or is wolffd@0: % completely zero) baseline to centre wolffd@0: zeroline='zero'; wolffd@0: elseif positive & ~negative wolffd@0: % Data contains only positive values: baseline to bottom wolffd@0: zeroline='bottom'; wolffd@0: elseif ~positive & negative wolffd@0: % Data contains only negative values: baseline to top wolffd@0: zeroline='top'; wolffd@0: end wolffd@0: case 'unitwise' wolffd@0: % scale the variables so that the bar for variable with the maximum wolffd@0: % value in the unit spans to the upper edge of the unit wolffd@0: % and the bar for the variable with minimum value spans to the lower edge, wolffd@0: % respectively. wolffd@0: zeroline='moving'; wolffd@0: case 'varwise' wolffd@0: % Check data max and min values wolffd@0: positive=any(data(:)>0); negative=any(data(:)<0); wolffd@0: if (positive & negative) | (~positive & ~negative), wolffd@0: % Data contains both negative and positive values (or is wolffd@0: % completely zero) baseline to wolffd@0: % centre, scale data so that it doesn't overflow wolffd@0: data=data./repmat(max(abs([max(data); min(data)])),N,1)*.5; wolffd@0: zeroline='zero'; wolffd@0: elseif positive & ~negative wolffd@0: % Data contains only positive values: baseline to wolffd@0: % bottom, scale data so that it doesn't overflow wolffd@0: data=data./repmat(max(abs([max(data); min(data)])),N,1)*.5; wolffd@0: zeroline='bottom'; wolffd@0: elseif ~positive & negative wolffd@0: % Data contains only negative values: baseline to wolffd@0: % top, scale data so that it doesn't overflow wolffd@0: zeroline='top'; wolffd@0: data=data./repmat(max(abs([max(data); min(data)])),N,1)*.5; wolffd@0: end wolffd@0: otherwise wolffd@0: error('Unknown scaling mode?'); wolffd@0: end wolffd@0: wolffd@0: for i=1:N, % calculate patch coordinates for wolffd@0: v=data(i,:); wolffd@0: [nx,ny]=vis_barpatch(v,gap,zeroline); % bars wolffd@0: barx(:,(1+(i-1)*d):(i*d))=s*nx; wolffd@0: bary(:,(1+(i-1)*d):(i*d))=s*ny; wolffd@0: end wolffd@0: l=size(barx,1); wolffd@0: wolffd@0: if size(msize,1) == 1, wolffd@0: xdim=msize(2); wolffd@0: ydim=msize(1); wolffd@0: if xdim*ydim~=N wolffd@0: error('Data matrix has wrong size.'); wolffd@0: else wolffd@0: y=reshape(repmat(1:ydim,d,1),1,d*ydim); y=repmat(repmat(y,l,1),1,xdim); wolffd@0: x=reshape(repmat(1:xdim,l*ydim*d,1),l,N*d); wolffd@0: end wolffd@0: else wolffd@0: x=reshape(repmat(msize(:,1),1,l*d)',l,d*N); wolffd@0: y=reshape(repmat(msize(:,2),1,l*d)',l,d*N); wolffd@0: if N ~= size(msize,1), wolffd@0: error('Data matrix has wrong size.'); wolffd@0: else wolffd@0: lattice='rect'; wolffd@0: if isnan(pos), wolffd@0: pos=[0 0]; wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % Check lattice wolffd@0: wolffd@0: if ~ischar(lattice) wolffd@0: error('Invalid lattice.'); wolffd@0: end wolffd@0: wolffd@0: switch lattice wolffd@0: case {'hexa','rect'} wolffd@0: pos=pos-1; wolffd@0: otherwise wolffd@0: error([ 'Lattice' lattice ' not implemented!']); wolffd@0: end wolffd@0: wolffd@0: % Check color wolffd@0: % C_FLAG is for color 'none' wolffd@0: wolffd@0: if nargin < 4 | isempty(color) wolffd@0: color=hsv(d); % default n hsv colors wolffd@0: end wolffd@0: if ~vis_valuetype(color, {[d 3],'nx3rgb'},'all') & ... wolffd@0: ~vis_valuetype(color,{'colorstyle','1x3rgb'}) wolffd@0: error('The color matrix has wrong size or has invalid values.'); wolffd@0: elseif ischar(color) & strcmp(color,'none') wolffd@0: C_FLAG=1; wolffd@0: color='w'; wolffd@0: else wolffd@0: C_FLAG=0; wolffd@0: end wolffd@0: wolffd@0: %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: % Making lattice. wolffd@0: % Command view([0 90]) shows the map in 2D properly oriented wolffd@0: wolffd@0: switch lattice wolffd@0: case 'hexa' wolffd@0: t=find(rem(y(1,:),2)); % move even rows by .5 wolffd@0: x(:,t)=x(:,t)-.5; wolffd@0: x=x+barx+.5; wolffd@0: y=y+bary; wolffd@0: case 'rect' wolffd@0: x=x+barx; wolffd@0: y=y+bary; wolffd@0: end wolffd@0: wolffd@0: % NB: The coordinates in hexa are not uniform in order to get even wolffd@0: % y-coordinates for the nodes. This is handled by setting _axis scaling_ wolffd@0: % so that the hexa-nodes look like uniform hexagonals. See wolffd@0: % vis_PlaneAxisProperties wolffd@0: wolffd@0: if ~isnan(pos) wolffd@0: x=x+pos(1);y=y+pos(2); % move upper left corner wolffd@0: end % to pos wolffd@0: wolffd@0: %% Set axes properties wolffd@0: wolffd@0: ax=newplot; % get current axis wolffd@0: vis_PlaneAxisProperties(ax,lattice, msize, pos); wolffd@0: wolffd@0: %% Rearrange dx3 color matrix wolffd@0: wolffd@0: if ~isstr(color) & size(color,1)~=1, wolffd@0: color=reshape(repmat(color,N,1),[1 N*d 3]); wolffd@0: end wolffd@0: wolffd@0: %% Draw the plane! wolffd@0: wolffd@0: if isnumeric(color), wolffd@0: % explicit color settings by RGB-triplets won't work with wolffd@0: % patch in 'painters' mode, unless there only a single triplet wolffd@0: si = size(color); wolffd@0: if length(si)~=2 | any(si==[1 3]), set(gcf,'renderer','zbuffer'); end wolffd@0: end wolffd@0: wolffd@0: h_=patch(x,y,color); wolffd@0: wolffd@0: if C_FLAG wolffd@0: set(h_,'FaceColor','none'); wolffd@0: end wolffd@0: wolffd@0: set(h_,'Tag','planeBar'); % tag the object wolffd@0: wolffd@0: %%% Build output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: if nargout>0, h=h_; end % Set h only if wolffd@0: % there really is output wolffd@0: wolffd@0: %%% Subfunctions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: function [xcoord,ycoord]=vis_barpatch(y,gap,zeroline) wolffd@0: wolffd@0: x = length(y); wolffd@0: d = gap/(2*(x-1)+2); wolffd@0: step= -.5:1/x:.5; wolffd@0: wolffd@0: miny=min(y); wolffd@0: maxy=max(y); wolffd@0: wolffd@0: switch(zeroline) wolffd@0: case 'moving' wolffd@0: if miny < 0 wolffd@0: if maxy > 0 wolffd@0: zl = .5 - (abs(miny)/(maxy-miny)); %reverse mode wolffd@0: y= .5 - ((y-miny*ones(1,x))./(maxy-miny)); wolffd@0: else wolffd@0: zl = -.5; wolffd@0: y=-.5+abs(y./miny); wolffd@0: end wolffd@0: else wolffd@0: zl = .5; %reverse mode wolffd@0: y=.5-y./maxy; wolffd@0: end wolffd@0: case 'moveNotScale' wolffd@0: if miny < 0 wolffd@0: if maxy > 0 wolffd@0: zl = 0.5+miny; wolffd@0: y = zl - y; wolffd@0: else wolffd@0: zl=-.5; wolffd@0: y=-.5+abs(y); wolffd@0: end wolffd@0: else wolffd@0: zl=.5; wolffd@0: y =.5-y; wolffd@0: end wolffd@0: case 'zero' wolffd@0: zl=0; y=zl-y; wolffd@0: case 'top' wolffd@0: zl=-.5; y=zl-2*y; wolffd@0: case 'bottom' wolffd@0: zl=.5; y=zl-2*y; wolffd@0: end wolffd@0: wolffd@0: for i=1:x wolffd@0: xcoord(:,i) = [d+step(i);d+step(i);step(i+1)-d;step(i+1)-d;d+step(i)]; wolffd@0: ycoord(:,i) = [zl;y(i);y(i);zl;zl]; wolffd@0: end wolffd@0: wolffd@0: wolffd@0: wolffd@0: wolffd@0: