Given a directed acyclic graph, there is always a possibility to plot the graph as layers, where nodes always send edges into one direction (usually down), to successive layers, and never backwards. The "LayeredDrawing"
option value for GraphLayout
fails miserably. There is the built-in (but somewhat obsolete) LayeredGraphPlot
, which can do this, but it is obviously not part of the new Graph
-paradigm. What would be an efficient and elegant algorithm to lay such a graph in 2D?
Row@{
Graph[{1 -> 2, 1 -> 3, 2 -> 3, 1 -> 4, 2 -> 4, 1 -> 5},
ImageSize -> 200, VertexLabels -> (# -> # & /@ Range@5),
GraphLayout -> "LayeredDrawing", ImagePadding -> 10],
LayeredGraphPlot[{1 -> 2, 1 -> 3, 2 -> 3, 1 -> 4, 2 -> 4, 1 -> 5},
VertexLabeling -> True, ImageSize -> 200]
}
Note, that while TopologicalSort
gives a top-down sorting of vertices, usually there are multiple solutions for topological sorting, thus multiple ways to layer the same graph. Also, the algorithm must take into account that not all children of a parent should end up on the same layer (see e.g. vertex 1
in the right plot). A nice algorithm for laying out arrows is welcome as well.
LayeredGraphPlot
. It helps to compute the transitive reduction of your graph first (if you want to draw all the edges, pick off the vertex coordinates from the layered plot of the transitive reduction and then plot the full graph). Transitive reduction was implemented in Combinatorica, but it's not included for Mathematica 8 Graph objects. Fortunately, they give youTopologicalSort
, so it's fairly easy to implement. $\endgroup$LayeredGraphPlot
does, in fact, work with Mathematica 8 nativeGraph
objects. $\endgroup$GraphPlot
and related functions are far from obsolete in v8.Graph
can't do everything they can (e.g. multigraphs). Graph drawing is complex enough to be a research field on its own so I am not sure if it's worthwhile trying to implement your own algorithm for this. $\endgroup$