10
$\begingroup$

I would like to organise a graph's vertices in levels. Consider

g = {
  0 -> 1, 1 -> 2, 2 -> 3, 0 -> 4, 0 -> 5, 2 -> 6, 2 -> 7, 8 -> 3, 4 -> 9, 5 -> 9, 
  6 -> 9, 6 -> 10, 7 -> 10, 8 -> 10, 9 -> 11, 9 -> 12, 10 -> 11, 10 -> 12 };
Graph[g]

Using nested list of vertices such as {{0, 1, 2, 3}, {4, 5, 6, 7, 8}, {9, 10}, {11, 12}}, I would like to see graph with 4 levels wherein vertices 0, 1, 2, 3 placed in line on the top level, vertices 4, 5, 6, 7, 8 in line on the level below and so on.

enter image description here

$\endgroup$
  • $\begingroup$ Which nodes would connect to which? $\endgroup$ – C. E. Oct 16 '13 at 8:15
  • $\begingroup$ If you were to add a diagram showing the result you are seeking, it would help clarify your question. As it is, I am unable conceive how you would like to see the output from Graph to look. $\endgroup$ – m_goldberg Oct 16 '13 at 8:30
  • $\begingroup$ nodes connection described in graph g and levels in nested list $\endgroup$ – Филипп Цветков Oct 16 '13 at 8:54
  • 1
    $\begingroup$ So you want to describe the vertex coordinates by the second list? Have a look at VertexCoordinates. $\endgroup$ – Sjoerd C. de Vries Oct 16 '13 at 9:15
7
$\begingroup$

You can use VertexCoordinates property

g = {0 -> 1, 1 -> 2, 2 -> 3, 0 -> 4, 0 -> 5, 2 -> 6, 2 -> 7, 8 -> 3, 
   4 -> 9, 5 -> 9, 6 -> 9, 6 -> 10, 7 -> 10, 8 -> 10, 9 -> 11, 
   9 -> 12, 10 -> 11, 10 -> 12};

levels = {{0, 1, 2, 3}, {4, 5, 6, 7, 8}, {9, 10}, {11, 12}};

graph = Graph[g, VertexLabels -> Placed["Name", Center], VertexSize -> Large];

Set vertex coordinates according to positions of vertices in levels:

graph2 = Fold[
  SetProperty[{#1, #2[[1]]}, VertexCoordinates -> #2[[2]]] &, graph, 
  Join @@ MapIndexed[Rule[#1, {#2[[2]] - Length[levels[[#2[[1]]]]]/2, -#2[[1]]}] &, 
   levels, {2}]]

enter image description here

See also this question.

Update

Inspired by the answer of István Zachar:

Graph[g, VertexLabels -> Placed["Name", Center], VertexSize -> Large, 
  VertexCoordinates -> ({#2, -#1} & @@@ 
    GraphEmbedding[Graph[g], {"MultipartiteEmbedding", "VertexPartition" -> {4, 5, 2, 2}}])]

enter image description here

$\endgroup$
  • $\begingroup$ Thank you! István Zachar's solution do not fit me because I use Mathematica 8.0 $\endgroup$ – Филипп Цветков Oct 16 '13 at 12:27
  • 1
    $\begingroup$ @ФилиппЦветков If you need a solution for Mathematica 8, please mention this in the question. $\endgroup$ – Szabolcs Oct 16 '13 at 17:10
10
$\begingroup$

In Mathematica 9+ one can use "MultipartiteEmbedding" with appropriate partitioning:

g = {0 -> 1, 1 -> 2, 2 -> 3, 0 -> 4, 0 -> 5, 2 -> 6, 2 -> 7, 8 -> 3, 
   4 -> 9, 5 -> 9, 6 -> 9, 6 -> 10, 7 -> 10, 8 -> 10, 9 -> 11, 
   9 -> 12, 10 -> 11, 10 -> 12};

Graph[g, GraphLayout -> {"MultipartiteEmbedding", "VertexPartition" -> {4, 5, 2, 2}},
   VertexLabels -> "Name"]

Mathematica graphics

Note that the embedding assumes (and partitions) the vertex list as it would be returned by VertexList[Graph[g]] so if you shuffle the edges, the vertex layout will be messed up.

Unfortunately, "MultipartiteEmbedding" does not accept the common method option "Orientation" -> Top, so one has to fall back to more primitive rotations:

Rotate[Graph[g, GraphLayout -> {"MultipartiteEmbedding",
    "VertexPartition" -> {4, 5, 2, 2}},
  VertexLabels -> (# -> Rotate[#, Pi/2] & /@ Range[0, 12])], -Pi/2]

Mathematica graphics

$\endgroup$

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.