Colouring rows of a tree

Hi,

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?

Thanks!

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:

Union@vlist

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.

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]} ] &)]

Nice! Thanks very much!

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?

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]]”