4
$\begingroup$

I have the following list of rules:

L={1->2,2->3,3->3};

and I want to plot a tree graph:

TreePlot[L,VertexRenderingFunction->({Disk[#,.02],Text[#2,#1+{.15,0}]}&)]

tree_graph

The thing is, I would like to have the arrows only on certain lines, such as the second one, 2->3. To this end, I shall write the rules as

L={{1->2,2->3,3->3},{False,True,False}};

and generate the tree by TreePlot[L[[1]],...]. My question is: how can I get the arrows only at True positions, as in the example above?

I thought I could use directed edges and undirected edges, that is,

L={UndirectedEdge[1,2],DirectedEdge[2,3],UndirectedEdge[3,3]};

but i get the message TreePlot::grph:L is not a valid graph.

How can I make it work?

$\endgroup$
  • 1
    $\begingroup$ Don't use the outdated TreePlot. Use Graph instead with GraphLayout $\endgroup$ – Szabolcs Oct 17 '15 at 15:29
  • $\begingroup$ How can I specify the root node in Graph? The third slot in TreePlot is the root node, but in Graph there is no mention (in the documentation) of the root node (I think). $\endgroup$ – AccidentalFourierTransform Oct 17 '15 at 16:04
  • $\begingroup$ When I wrote the comment, I didn't realize that it's not going to go as smoothly as it should ... I wrote a more detailed answer. The graph layouts are documented in the GraphLayout doc page. There's a lot of information squeezed in there about lots and lots of different layout methods, their suboptions, etc. It's a bit confusion as usually this amount of stuff wouldn't be hidden behind a single options and its suboptions. It's too easy to miss. $\endgroup$ – Szabolcs Oct 17 '15 at 17:32
4
$\begingroup$

TreePlot is the old way to plot trees. It has been superseded by Graph and GraphLayout. GraphLayout -> "LayeredEmbedding" can be used for trees. Please check the documentation on how to set various options for this embedding, including specifying the root: GraphLayout. They're a bit hidden down the page.

Mathematica 10 and later supports mixed graphs with both directed and undirected edges. One way to accomplish what you want is to use these. Unfortunately "LayeredGraphEmbedding" doesn't seem to support them. As a workaround we create an undirected graph, compute the vertex coordinates, then apply them to our mixed graph.

g = Graph[{1 <-> 2, 2 -> 3, 3 <-> 3}, VertexLabels -> "Name"]

Mathematica graphics

UndirectedGraph[g, 
   GraphLayout -> {"LayeredEmbedding", "RootVertex" -> 2}]

Mathematica graphics

pts = GraphEmbedding[%];

SetProperty[g, VertexCoordinates -> pts]

Mathematica graphics

Alternatively, this last step could be replaces by custom code that takes pts, the edge list, some directedness specification for the edges, and draws the edges manually, putting the arrowheads where necessary.

$\endgroup$
1
$\begingroup$

If you have to use TreePlot, you can also

Use EdgeRenderingFunction:

TreePlot[L, VertexRenderingFunction -> ({Disk[#, .02], Text[#2, #1 + {.05, .025}]} &), 
 EdgeRenderingFunction -> ({Darker@Red, 
     If[#2 === {2, 3}, {Arrowheads[{0, 0, .05, 0}], Arrow[#]}, Line[#]]} &)]

enter image description here

Post-process selected Lines to Arrows:

TreePlot[L, VertexRenderingFunction -> ({Disk[#, .02], Text[#2, #1 + {.05, .025}]} &)] /. 
 Line[x_] :> (Line /@ x ) /. 
 Line[{2, 3}] :> {Arrowheads[{0, 0, .05, 0}], Arrow[{2, 3}]}

enter image description here

$\endgroup$
  • $\begingroup$ Nice! I was already using VertexRenderingFunction, but it didn't occur to me that one can also use EdgeRenderingFunction for a similar purpose (but to modify edges instead of vertices). Thank you very much! $\endgroup$ – AccidentalFourierTransform Nov 27 '17 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.