www.gusucode.com > wavelet工具箱matlab源码程序 > wavelet/wmultisig1d/wtbxdendrogram.m

    function [h,T,perm,theGroups] = wtbxdendrogram(Z,varargin)
%WTBXDENDROGRAM Generate dendrogram plot.

%   M. Misiti, Y. Misiti, G. Oppenheim, J.M. Poggi 26-Jun-2006.
%   Last Revision: 20-Jul-2010.
%   Copyright 1995-2010 The MathWorks, Inc.

m = size(Z,1)+1;
p = varargin{1};
if nargin > 2
    color = true;
    threshold = varargin{3};
else
    color = false;
    threshold = 0.7 * max(Z(:,3));
end
                    
% For each node currently labeled m+k, replace its index by
% min(i,j) where i and j are the nodes under node m+k.
Z = transz(Z);
T = (1:m)';

% If there are more than p nodes, the dendrogram looks crowded.
% The following code will make the last p link nodes into leaf nodes,
% and only these p nodes will be visible.
if (m > p) && (p ~= 0)
    Y = Z((m-p+1):end,:);         % get the last nodes
    R = unique(Y(:,1:2)); 
    Rlp = R(R<=p);
    Rgp = R(R>p);
    W(Rlp) = Rlp;                 % use current node number if <=p
    W(Rgp) = setdiff(1:p, Rlp);   % otherwise get unused numbers <=p
    W = W(:);
    T(R) = W(R);
    % Assign each leaf in the original tree to one of the new node numbers
    for i = 1:p
        c = R(i);
        T = clusternum(Z,T,W(c),c,m-p+1,0); % assign to its leaves.
    end
    % Create new, smaller tree Z with new node numbering
    Y(:,1) = W(Y(:,1));
    Y(:,2) = W(Y(:,2));
    Z = Y;
    m = p; % reset the number of node to be 30 (row number = 29).
end
A = zeros(4,m-1);
B = A;
n = m;
X = 1:n;
Y = zeros(n,1);
r = Y;

% arrange Z into W so that there will be no crossing in the dendrogram.
W = zeros(size(Z));
W(1,:) = Z(1,:);
nsw = zeros(n,1); rsw = nsw;
nsw(Z(1,1:2)) = 1; rsw(1) = 1;
k = 2; s = 2;
while (k < n)
    i = s;
    while rsw(i) || ~any(nsw(Z(i,1:2)))
        if rsw(i) && i == s, s = s+1; end
        i = i+1;
    end
    W(k,:) = Z(i,:);
    nsw(Z(i,1:2)) = 1;
    rsw(i) = 1;
    if s == i, s = s+1; end
    k = k+1;
end
g = 1;
for k = 1:m-1 % initialize X
    i = W(k,1);
    if ~r(i) , X(i) = g;  g = g+1;  r(i) = 1;  end
    i = W(k,2);
    if ~r(i),  X(i) = g;  g = g+1;  r(i) = 1;  end
end
[~,perm] = sort(X);   % perm is the third output value
label = num2str(perm');

% set up the color
theGroups = 1;
groups = 0;
cmap = [0 0 1];
if color
    groups = sum(Z(:,3)< threshold);
    if groups > 1 && groups < (m-1)
        theGroups = zeros(m-1,1);
        numColors = 0;
        for count = groups:-1:1
            if (theGroups(count) == 0)
                P = zeros(m-1,1);
                P(count) = 1;
                P = colorcluster(Z,P,Z(count,1),count);
                P = colorcluster(Z,P,Z(count,2),count);
                numColors = numColors + 1;
                theGroups(logical(P)) = numColors;
            end
        end 
        cmap = hsv(numColors);
        cmap(end+1,:) = [0 0 0]; 
    else
        groups = 1;
    end
end  
newplot;

col = zeros(m-1,3);
h = zeros(m-1,1);
for n = 1:(m-1)
    i = Z(n,1); j = Z(n,2); w = Z(n,3);
    A(:,n) = [X(i) X(i) X(j) X(j)]';
    B(:,n) = [Y(i) w w Y(j)]';
    X(i) = (X(i)+X(j))/2; Y(i)  = w;
    if n <= groups
        col(n,:) = cmap(theGroups(n),:);
    else
        col(n,:) = cmap(end,:);
    end
end
ymin = min(Z(:,3));
ymax = max(Z(:,3));
margin = (ymax - ymin) * 0.05;
n = size(label,1);
for count = 1:(m-1)
    h(count) = line(A(:,count),B(:,count),'Color',col(count,:));
end
lims = [0 m+1 max(0,ymin-margin) (ymax+margin)];
set(gca,'XLim',[.5 ,(n +.5)],'XTick',1:n, 'XTickLabel',label,'Box','off');
mask = logical([0 0 1 1]);
if margin==0
    if ymax~=0
        lims(mask) = ymax * [0 1.25];
    else
        lims(mask) = [0 1];
    end
end
axis(lims);
%--------------------------------------------------------------------------
function T = clusternum(X, T, c, k, m, d)
% assign leaves under cluster c to c.
d = d+1;
n = m; flag = 0;
while n > 1
    n = n-1;
    if X(n,1) == k % node k is not a leave, it has subtrees
        T = clusternum(X, T, c, k, n,d); % trace back left subtree
        T = clusternum(X, T, c, X(n,2), n,d);
        flag = 1; break;
    end
end
if flag == 0 && d ~= 1 % row m is leaf node.
    T(X(m,1)) = c;
    T(X(m,2)) = c;
end
%--------------------------------------------------------------------------
function T = colorcluster(X, T, k, m)
% find local clustering
n = m; 
while n > 1
    n = n-1;
    if X(n,1) == k % node k is not a leave, it has subtrees
        T = colorcluster(X, T, k, n); % trace back left subtree
        T = colorcluster(X, T, X(n,2), n);
        break;
    end
end
T(m) = 1;
%--------------------------------------------------------------------------
function Z = transz(Z)
%TRANSZ Translate output of LINKAGE into another format.
%   This is a helper function used by DENDROGRAM and COPHENET.  
%   In LINKAGE, when a new cluster is formed from cluster i & j, it is
%   easier for the latter computation to name the newly formed cluster
%   min(i,j). However, this definition makes it hard to understand
%   the linkage information. We choose to give the newly formed
%   cluster a cluster index M+k, where M is the number of original
%   observation, and k means that this new cluster is the kth cluster
%   to be formed. This helper function converts the M+k indexing into
%   min(i,j) indexing.
m = size(Z,1)+1;
for i = 1:(m-1)
    if Z(i,1) > m ,      Z(i,1) = traceback(Z,Z(i,1)); end
    if Z(i,2) > m ,      Z(i,2) = traceback(Z,Z(i,2)); end
    if Z(i,1) > Z(i,2) , Z(i,1:2) = Z(i,[2 1]);        end
end
%----------------------------------------------------------
function a = traceback(Z,b)
m = size(Z,1)+1;
if Z(b-m,1) > m , a = traceback(Z,Z(b-m,1));  else  a = Z(b-m,1); end
if Z(b-m,2) > m , c = traceback(Z,Z(b-m,2));  else  c = Z(b-m,2); end
a = min(a,c);
%--------------------------------------------------------------------------