Dendrogram node line thickness based on node population

3 次查看(过去 30 天)
I am trying to alter a dendrogram to provide a visual indication of the population at each node. For the terminal nodes, I am able to match the thickness of the line by:
leaveshistogram = hist(T, 1:leaves);
for x = 1:leaves-1
set(H(x),'LineWidth', leaveshistogram(x));
end;
This alters the line width property to the number of elements in the same leaf node within the histogram function output. (Only works with small numbers, for large populations, a scaling factor would be needed)
The output looks like this:
I want to sum the populations in two leaves, and alter the width of the internal edges within the dendrogram, such that the edges get wider and wider until the root has a line width equivalent to "100%" of the population.
To accomplish this, I also need to find the handles for the internal nodes and internal edges within the dendrogram, they are not stored in the H output.

回答(1 个)

Kelly Kearney
Kelly Kearney 2016-5-11
The line handles returned by the dendrogram function correspond to the pairs in the z. You can see this more clearly if you color each line object separately:
x = rand(10,2);
y = pdist(x);
z = linkage(y);
val = 1:10;
h = dendrogram(z, 0);
set(h, {'color'}, num2cell(jet(length(h)),2));
and compare to z:
z =
1 10 0.12893
2 4 0.14701
9 11 0.15693
3 13 0.17518
7 14 0.21876
6 8 0.24399
12 15 0.25473
16 17 0.27626
5 18 0.31967
So h(1) connects leaf 1 to leaf 10, h(2) connects leaf 2 to leaf 4, h(3) connects leaf 9 to group 11 (and group 11 = the leaf 1 + leaf 10 group), etc. In order to get the alterations you want, you'll have to retrieve the x/y data from each line segment, break it into two at the midpoint of the horizontal crossbar, and change the width accordingly.
Might be able to post an example in a bit, if I get some time...
  2 个评论
Kelly Kearney
Kelly Kearney 2016-5-11
This almost does the trick, assuming you start with all nodes showing... but it seems that the direction of the line occasionally flips around from what I was expecting (for example, I'm flipping the proper widths for the line that connects 2 with 12+20). Something to play with, though... The colors are just there so I could see which part of the code was drawing each line segment.
rng('default');
x = rand(20,2);
y = pdist(x);
z = linkage(y);
nx = size(x,1);
nz = size(z,1);
[h, T, outperm] = dendrogram(z, 0);
nleaf = max(T);
val = nan(nx+nz,1);
val(1:nx) = hist(T, 1:nx);
for ii = 1:nz
val(ii+nx) = sum(val(z(ii,1:2)));
end
lw = val(z(:,1:2));
hnew = gobjects(size(h));
for ii = 1:length(h)
if lw(ii,1) == lw(ii,2)
% Same width on both sides, don't need to break
set(h(ii), 'linewidth', lw(ii,1));
set(h(ii), 'color', 'r');
else
xmid = mean(h(ii).XData(2:3));
ymid = mean(h(ii).YData(2:3));
x1 = [h(ii).XData(1:2) xmid];
x2 = [xmid h(ii).XData(3:4)];
y1 = [h(ii).YData(1:2) ymid];
y2 = [ymid h(ii).YData(3:4)];
h(ii).XData = x1;
h(ii).YData = y1;
h(ii).LineWidth = lw(ii,1);
if lw(ii,1) > lw(ii,2)
hnew(ii) = line(x2, y2, 'linewidth', lw(ii,2), 'color', 'g');
h(ii).LineWidth = lw(ii,1);
else
hnew(ii) = line(x2, y2, 'linewidth', lw(ii,1), 'color', 'm');
h(ii).LineWidth = lw(ii,2);
end
end
end
Michele
Michele 2016-5-11
Thanks!
I don't think we need to have all nodes showing. The output T from dendrogram will provide the leaf node location for each original data point, and this can be counted to give the leaf node populations.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Agriculture 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by