I was trying to recreate following graphviz graph with Mathematica 11.2:
graph {
rankdir=LR;
a -- { b c d }; b -- { c e }; c -- { e f }; d -- { f g }; e -- h; f -- { h i j g };
g -- k; h -- { o l }; i -- { l m j }; j -- { m n k }; k -- { n r }; l -- { o m };
m -- { o p n }; n -- { q r }; o -- { s p }; p -- { s t q }; q -- { t r }; r -- t;
s -- z; t -- z;
{ rank=same; b, c, d }
{ rank=same; e, f, g }
{ rank=same; h, i, j, k }
{ rank=same; l, m, n }
{ rank=same; o, p, q, r }
{ rank=same; s, t }
}
As you can see, you can specify in the dot language that certain nodes have the same 'rank', i.e. are located on the same layer.
How can I do this in Mathematica 11.2?
IMO this question has already been asked:
- Graph plotting: specify layers for layered drawing
- Plotting Network with LayeredGraphPlot with specific order
However, both questions are not satisfying:
- The first one gives no example graph and hence never got answered.
- The second has gotten an answer specific to the example (actual manual placement).
Furthermore, both questions are 4 years old, i.e. new Mathematica versions have appeared.
I have tried three approaches in Mathematica.
Using newer
Graph
command withGraphLayout -> {"LayeredEmbedding"}
Graph[{"a" <-> "b", "a" <-> "c", "a" <-> "d", "b" <-> "c", "b" <-> "e", "c" <-> "e", "c" <-> "f", "d" <-> "f", "d" <-> "g", "e" <-> "h", "f" <-> "h", "f" <-> "i", "f" <-> "j", "f" <-> "g", "g" <-> "k", "h" <-> "o", "h" <-> "l", "i" <-> "l", "i" <-> "m", "i" <-> "j", "j" <-> "m", "j" <-> "n", "j" <-> "k", "k" <-> "n", "k" <-> "r", "l" <-> "o", "l" <-> "m", "m" <-> "o", "m" <-> "p", "m" <-> "n", "n" <-> "q", "n" <-> "r", "o" <-> "s", "o" <-> "p", "p" <-> "s", "p" <-> "t", "p" <-> "q", "q" <-> "t", "q" <-> "r", "r" <-> "t", "s" <-> "z", "t" <-> "z"}, GraphLayout -> {"LayeredEmbedding", "Orientation" -> Left}, VertexShapeFunction -> "Circle", VertexSize -> {.2, .1}, VertexStyle -> White, VertexLabels -> Placed["Name", Center], EdgeStyle -> Black, EdgeShapeFunction -> { "p" <-> "q" -> {"CurvedArc", "Curvature" -> -0.66}, "p" <-> "t" -> {"CurvedArc", "Curvature" -> -0.66}, "m" <-> "o" -> {"CurvedArc", "Curvature" -> 1} }]
UPDATED:
- Orientation (comment by kglr)
- Specified edges which should be curved otherwise they are hidden (answer by kglr)
Using older
GraphPlot
command with promising featureVertexCoordinateRules
:GraphPlot[{"a" -> "b", "a" -> "c", "a" -> "d", "b" -> "c", "b" -> "e", "c" -> "e", "c" -> "f", "d" -> "f", "d" -> "g", "e" -> "h", "f" -> "h", "f" -> "i", "f" -> "j", "f" -> "g", "g" -> "k", "h" -> "o", "h" -> "l", "i" -> "l", "i" -> "m", "i" -> "j", "j" -> "m", "j" -> "n", "j" -> "k", "k" -> "n", "k" -> "r", "l" -> "o", "l" -> "m", "m" -> "o", "m" -> "p", "m" -> "n", "n" -> "q", "n" -> "r", "o" -> "s", "o" -> "p", "p" -> "s", "p" -> "t", "p" -> "q", "q" -> "t", "q" -> "r", "r" -> "t", "s" -> "z", "t" -> "z"}, VertexLabeling -> True, DirectedEdges -> False, VertexCoordinateRules -> Flatten[{ (# -> {0, Automatic}) & /@ {"a"}, (# -> {1, Automatic}) & /@ {"b", "c", "d"}, (# -> {2, Automatic}) & /@ {"e", "f", "g"}, (# -> {3, Automatic}) & /@ {"h", "i", "j", "k"}, (# -> {4, Automatic}) & /@ {"l", "m", "n"}, (# -> {5, Automatic}) & /@ {"o", "p", "q", "r"}, (# -> {6, Automatic}) & /@ {"s", "t"}, (# -> {7, Automatic}) & /@ {"z"} }, 1]]
Using older
LayeredGraphPlot
(only supportsVertexCoordinateRules
withSpringElectricalEmbedding
)LayeredGraphPlot[{"a" -> "b", "a" -> "c", "a" -> "d", "b" -> "c", "b" -> "e", "c" -> "e", "c" -> "f", "d" -> "f", "d" -> "g", "e" -> "h", "f" -> "h", "f" -> "i", "f" -> "j", "f" -> "g", "g" -> "k", "h" -> "o", "h" -> "l", "i" -> "l", "i" -> "m", "i" -> "j", "j" -> "m", "j" -> "n", "j" -> "k", "k" -> "n", "k" -> "r", "l" -> "o", "l" -> "m", "m" -> "o", "m" -> "p", "m" -> "n", "n" -> "q", "n" -> "r", "o" -> "s", "o" -> "p", "p" -> "s", "p" -> "t", "p" -> "q", "q" -> "t", "q" -> "r", "r" -> "t", "s" -> "z", "t" -> "z"}, Left, DirectedEdges -> False, VertexLabeling -> True]
Each with limitations, but most importantly only VertexCoordinateRules
seem to be a possibility to have something similar as in the dot language.
Issues/Questions
How can I switch the orientation in my first approach? Also a few edges are not visible, e.g. edgep--q
(a tiny bit thicker edgesp--s
ands--q
).- For the most promising second approach, the edge
h--o
is almost not visible:h--o
is bended in the graphviz version (as done in approach 3). How I can I fix this? - I could imagine to use the first or third approach to generate a first layout and then manually fix the x-value of the nodes. How could I do this?
AbsoluteOptions[graph, VertexCoordinates]
to retrieve the actual coordinates used by aGraph[]
object. $\endgroup$GraphEmbedding
. $\endgroup$GraphEmbedding
was in the "See Also" forGraphLayout
... $\endgroup$GraphLayout -> {"LayeredDigraphEmbedding", "Orientation" -> Left}
$\endgroup$Graph
viaVertexCoordinates ->
. $\endgroup$