Can TreeForm be displayed “sideways”?

One recurrent problem I'm having with displays generated with TreeForm is that the expressions to be so displayed often at least one level with many (> 20) nodes at, which results in many overlapping labels that obscure each other.1

One simple way to mitigate the problem would be to display the same tree "sideways" (i.e., rotated 90 degrees, as would be the case if the display had been generated by a TreePlot command with the Left orientation parameter, for example). Of course, for this strategy to be at all useful, it is necessary that only the geometrical arrangement of the nodes and edges be rotated, not the labels. The latter should remain in the standard "horizontal"/left-to-right/text orientation.

I'm stymied by the fact that the output of TreeForm only looks like a Graphics object, but isn't really one. Is there a way to get Mathematica to return the Graphics object corresponding to the displayed image? Better yet would be to get the equivalent TreePlot command.

EDIT:

1 For example, the following shows the kind of tree I'm trying to work with:

g = Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 Pi},
PlotStyle -> {Red, Green, Blue}];
TreeForm[g /. x_ /; And @@ NumericQ /@ x :> x[[0]] /. x_[List] :> x]

-
What do you mean by "the output of TreeForm only looks like a Graphics object, but isn't really one."? It is made up of graphics primitives... Did you mean to say it looks like a Graph object, but isn't one? – R. M. Sep 20 '13 at 19:06
@rm-rf: Maybe I'm not interpreting what I'm seeing correctly, but if I run TreeForm[x+y], and then run FullForm[%], what I get is Plus[x, y], and not Graphics[...]. This suggests that TreeForm does not really produce a Graphics object, but is merely a display directive... Again, I may not be interpreting what I'm seeing correctly... – kjo Sep 20 '13 at 19:22

ExpressionTreePlot (update, thanks to @Belisarius)

The GraphUtilities package contains a function that will do the trick:

Needs["GraphUtilities"]
ExpressionTreePlot[1+Sin[x^2], Left]


ExprTreePlot (my original response)

If you do not mind using an undocumented function, then NetworkGraphPlotExprTreePlot can do the job:

NetworkGraphPlotExprTreePlot[1+Sin[x^2], Left]


The arguments to this function are:

ExprTreePlot[expr_, orientation_:Top, maxlevel_:Infinity, format_:StandardForm, options___]


Of course, all the usual caveats apply: there is no official support, the feature may be removed from future versions, etc. But it gives us convenient access to all the usual choices for root node placement:

Table[
NetworkGraphPlotExprTreePlot[1+Sin[x^2], orientation]
, {orientation , {Left, Right, Top, Bottom, Center}}
] // GraphicsColumn[#, ImageSize -> {200, Automatic}, Frame -> All]&


Recovering the TreePlot

As an alternative, we could extract the TreePlot generated by TreeForm. The complication is that TreeForm is an inert wrapper. The generation of the TreePlot happens when the front-end creates the box form. The good news is that we can use MakeBoxes to extract the TreePlot in held form:

Block[{TreePlot}
, t_TreePlot := Throw @ Hold @ t
; Catch @ MakeBoxes @ TreeForm[1+Sin[x^2]]
]

(*
Hold[TreePlot[
{{"Plus","0","         2\n1 + Sin[x ]"}->{"1","1","1"},...},
Top,
{"Plus","0","         2\n1 + Sin[x ]"},
AlignmentPoint->Center,
AspectRatio->Automatic,
...]]
*)


Beware that the recovered TreePlot expression may use undocumented constructs that generate (harmless) warnings. Such warnings are normally muffled by the front-end's box generation process.

-
I've added a section on how to recover the TreePlot. – WReach Sep 21 '13 at 3:46
I've simplified the code used to recover the TreePlot. – WReach Apr 11 '14 at 14:41
I think it's documented here reference.wolfram.com/mathematica/GraphUtilities/tutorial/… – Dr. belisarius Apr 14 '14 at 12:12
@belisarius Thanks for the pointer... I've updated my response. – WReach Apr 14 '14 at 14:13
@WReach, as of M10, ExpressionTreePlot is deprecated: reference.wolfram.com/language/GraphUtilities/ref/… – alancalvitti Jun 26 '14 at 14:05

Here's a possible way, using TreeForm directly, and with VertexRenderingFunction. I think this is what you describe in your second paragraph. I hope this is useful to you

TreeForm[1 + Sin[x^2],
VertexRenderingFunction -> (Inset[Panel@Rotate[#2, -π/2], #1] &)] //
Rotate[#, π/2] &


-

Similar to Pinguin Dirk answer but with the standard style

RotatedTreeForm[x_] :=
Rotate[TreeForm[x,
VertexRenderingFunction -> (Rotate[
Inset[Framed[Style[#2, "StandardForm", "Output",
FontSize -> Scaled[0.1]], Background -> LightYellow,
FrameStyle -> GrayLevel[0.5]], #1], -\[Pi]/2] &)], \[Pi]/2];

Cos[Exp[x]] // RotatedTreeForm


-
you know, I love Panel, I guess I use it way too often :) – Pinguin Dirk Sep 20 '13 at 19:37
@ybeltukov Nice solution, but it should be noted that one needs to count from bottom to top, which is counter intuitive. For example, e has the coordinate {1,1} and Plus - {1,2} – Alexei Boulbitch Apr 24 '14 at 8:10

Using the undocumented function SparseArrayExpressionToTree

expr = 1 + Sin[x^2];
ett = SparseArrayExpressionToTree[expr];
(* {{Plus,0,1+Sin[x^2]}->{1,1,1},
{Plus,0,1+Sin[x^2]}->{Sin,2,Sin[x^2]},
{Sin,2,Sin[x^2]}->{Power,3,x^2},
{Power,3,x^2}->{x,4,x},
{Power,3,x^2}->{2,5,2}}*)

edges = ett[[All, All, 1]];
(* {Plus->1,Plus->Sin,Sin->Power,Power->x,Power->2} *)

Graph[edges,
VertexLabels -> Placed["Name", {Center, Center}],
VertexSize -> {"Scaled", .12}, VertexLabelStyle -> 20,
VertexShapeFunction -> "Rectangle",
GraphLayout -> {"LayeredEmbedding", "RootVertex" -> edges[[1, 1]],"Orientation" -> Left},
ImagePadding -> 20, ImageSize -> 600]


Note: This works in Version 9.0.1.0.

-
See also (for people like me who coincidentally saw the question 3 days after this answer was posted) – hftf Jun 30 '14 at 14:53