Colour the tick lables in a dendrogram to match the cluster colours

半腔热情 提交于 2019-12-30 14:38:45

问题


How can I individually colour the labels of a dendrogram so that they match the colours of the clusters in MATLAB?

Here is an example desired output generated using the code in my answer below (note the lables are just the 50 charater series 'A':'r'):

If there is a more straightforward way to do this, please do post an answer as I was unable to find the solution to this by googling. If not, the code is below for posterity.


回答1:


I could not find a definitive answer to this but I managed to piece the following together from a couple of ideas (shown in the comments) I found online. Hopefully this is useful to someone.

I'm assuming that your data you are clustering is in the matrix data and that labels are stored in a cell array called 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


来源:https://stackoverflow.com/questions/34947840/colour-the-tick-lables-in-a-dendrogram-to-match-the-cluster-colours

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!