Message Boards Message Boards

5 Replies
7 Total Likes
View groups...
Share this post:

Colouring rows of a tree


Is it possible to draw a tree using TreePlot[] and to colour opposite rows of the output different colours? Ideally I would like to use different background colours for different rows. I did think about using different vertex colours but it seems that the vertex styling function isn't passed row information. Is there any way to do this?

POSTED BY: Mark Green
5 Replies
treeLevel[tree_, x_] :=
Module[{parent, p}, Print[{parent, p}]; Print@{tree, (p_ -> x) -> p};
parent = Cases[tree, (p_ -> x) -> p]; Print[{parent, p}];
If[parent == {}, 1, treeLevel[tree, parent[[0]]] + 1]]
I didn't see the issue at first myself, but if you insert some print statements, debugging shows that parent[[0]] gives the head, List. Mathematica indexes lists from 1 to their length instead of from 0 to their length-1, so replace "parent[[0]]" with "parent[[1]]"
POSTED BY: Sean Clarke
I've been looking at this and wondering if it's possible to get the hierarchy level of each node by means other than pre-running TreePlot and capturing its output. I've tried to write a function to do this but it doesn't seem to behave itself.
treeLevel[tree_, x_] := Module[{parent, p}, parent = Cases[tree, (p_ -> x) -> p];
  If[parent == {}, 1, treeLevel[tree, parent[[0]]] + 1]]
The problem is, its output is never higher than 2. Can anyone clarify what's wrong with this, please?
POSTED BY: Mark Green
Nice! Thanks very much!
POSTED BY: Mark Green
As an example, given that "hierarchy" has been defined like above, we can find which level in the heirarchy a vertex, say v, belongs to:
Position[hierarchy, v, 2][[1, 1]]
Put this into a switch and you have a VertexRenderingFunction:
TreePlot[{1 -> 4, 1 -> 6, 1 -> 8, 2 -> 6, 3 -> 8, 4 -> 5, 7 -> 8}, VertexRenderingFunction ->(Switch[Position[hierarchy, #2, 2][[1, 1]], 1, {Red, Disk[#1, 0.1]}, 2, {Black, Disk[#1, 0.1]} , 3, {Blue, Disk[#1, 0.1]} ] &)]
POSTED BY: Sean Clarke
Hi. What did you mean by rows? Are you refering to the vertices that line up together in a certain layout like the top layout?

If so, TreePlot doesn't seem to make this easy. As a first step, I would gather the locations of where TreePlot planned on putting the vertices by running the function once an appending their names and locations onto a list to use:
vlist = {};
TreePlot[{1 -> 4, 1 -> 6, 1 -> 8, 2 -> 6, 3 -> 8, 4 -> 5, 7 -> 8},
VertexRenderingFunction -> (AppendTo[vlist, {Last@#1, #2}]; &)];

Sow and Reap are often useful in these situations as well. "vlist" is now a list of pairs of "y" values and the corresponding vertex name.
Run Union on it to remove duplicate entries and to sort them:
Gather the entries together by their first value:
GatherBy[Union@vlist, First]
Use Map and Part together to strip out the y values:
hierarchy = #[[All, 2]] & /@ GatherBy[Union@vlist, First]
This expression results in {{2, 3, 5, 7}, {4, 6, 8}, {1}}, which are the names of the vertices grouped together by their row from bottom to top. You can now use this in the construction of a VertexRenderingFunction for the original TreePlot.
POSTED BY: Sean Clarke
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract