
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.
0 件のコメント
回答 (1 件)
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
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

参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!