在树形图中为滴答标记着色以匹配簇颜色

时间:2016-01-22 13:28:31

标签: matlab plot cluster-analysis hierarchical-clustering dendrogram

如何单独为树形图的标签着色,使它们与MATLAB中的簇的颜色相匹配?

下面是我在下面的答案中使用代码生成的所需输出示例(注意标签只是50个字符系列'A':'r'):

enter image description here

如果有更简单的方法,请发布答案,因为我无法通过谷歌搜索找到解决方案。如果没有,代码在下面为后代。

1 个答案:

答案 0 :(得分:0)

我无法找到明确的答案,但我设法将以下内容从我在网上发现的一些想法(显示在评论中)中拼凑出来。希望这对某人有用。

我假设你正在聚类的数据在矩阵data中,并且labels存储在名为标签的单元格数组中:

%% Hierarchical clustering
T = linkage(data,'average','spearman');
D = pdist(data, 'spearman');
leafOrder = optimalleaforder(T, D);
th = 0.726;
H = dendrogram(T, 0,'ReOrder', leafOrder, 'Orientation', 'left', 'ColorThreshold', th);
h = gca;
set(h, 'YTickLabel', labels(leafOrder));

%Changing the colours

%First get a list of the colours of each line object
lineColours = cell2mat(get(H,'Color'));
colourList = unique(lineColours, 'rows');
% For each cluster (i.e. for each unique colour)
for colour = 1:size(colourList,1)
    % see http://stackoverflow.com/a/16677119/1011724 for the idea of
    % copying the axis
    ax = copyobj(gca, gcf);
    % see http://undocumentedmatlab.com/blog/customizing-axes-rulers for
    % more on YRuler. This might not work on older versions of MATLAB.
    yruler = ax.YRuler;
    rgb = floor(colourList(colour,:)'*255);
    % Make all the datalabels of the new axis the current colour. (We will
    % later make those labels that aren't this colour empty.)
    yruler.TickLabels.ColorData = uint8([rgb;255]);
    % Might not be necessary, but stopped me getting errors
    pause(0.1) 

    % The hard bit is figuring out which line object matches which label
    % Note that there might be an easier way if you are willing to alter your dendrogram.m file: http://www.mathworks.com/matlabcentral/newsreader/view_thread/134997
    idx = ismember(lineColours, colourList(colour,:), 'rows');
    clusterNodes = [T(idx,1);T(idx,2)];
    % Cluster nodes greater than the number of data points are none terminal
    % nodes and thus not of interest.
    [~,c]=find(bsxfun(@eq,clusterNodes(clusterNodes < length(labels)+1),leafOrder))
    % Convert to a logical index
    idx = ~ismember(1:(size(lineColours,1)+1), c);
    n = sum(idx);
    % Set the labels we don't want to colour (this iteration) to be empty
    % char arrays.
    yruler.TickLabels.String(idx) = mat2cell(repmat(char(),n,1),zeros(n,1),0);
end