Bernhard Boehmler
Bernhard Boehmler

Reputation: 75

How to position subgraphs horizontally centered above each other with dot?

my code

digraph g
{
rankdir=RL
node
[shape = record, height=0.1];
subgraph
1
{
M_1; M_4; M_8; M_11;
}
subgraph
2
{
M_2; M_5; M_9;
}
subgraph
3
{
M_3; M_6; M_10;
}
subgraph
5
{
rank
=
same
M_2; M_3;
}
subgraph
8
{
rank
=
same
M_5; M_6; M_7;
}
subgraph
11
{
rank
=
same
M_10; M_9;
}
subgraph
12
{
rank
=
same
M_5; M_7; M_6;
}
M_1 -> M_4 [style=dotted, weight=100];
M_4 -> M_8 [style=dotted, weight=100];
M_8 -> M_11 [style=dotted, weight=100];
M_2 -> M_5 [style=dotted, weight=100];
M_5 -> M_9 [style=dotted, weight=100];
M_3 -> M_6 [style=dotted, weight=100];
M_6 -> M_10 [style=dotted, weight=100];
M_2 -> M_1;
M_4 -> M_2;
M_3 -> M_1;
M_4 -> M_3;
M_5 -> M_4;
M_6 -> M_4;
M_8 -> M_5;
M_8 -> M_6;
M_7 -> M_4;
M_8 -> M_7;
M_9 -> M_8;
M_10 -> M_8;
M_11 -> M_10;
M_11 -> M_9;
}

gives the following output:

enter image description here

Now, my question is:

How can I center the lines $M_2, M_5, M_9$ and $M_1, M_4, M_8, M_{11}$ and $M_3, M_6, M_{10}$ horizontally?

Since $M_5, M_6$ and $M_7$ are forced to have the same rank, as well as $M_2$ and $M_3$ and so forth, this should eventually give a nice picture, where the boxes of the nodes are positioned in such a way that it looks very symmetrical.

Is there a way to do this with dot?

Thanks for the help!

Upvotes: 2

Views: 5279

Answers (1)

stefan
stefan

Reputation: 3759

Nodes in the same group are placed on a straight line down the rank. All your edges assist nicely in ranking if given the right dir attribute.

digraph g
{
    rankdir=RL
    node [shape = record, height=0.1];
    subgraph {
        node [group=2]
        M_2; M_5; M_9;
    }
    subgraph {
        node [group=1]
        M_1; M_4; M_8; M_11;
    }
    subgraph {
        node [group=3]
        M_3; M_6; M_10;
    }
    M_7;
    subgraph {
        edge [style=dotted]
        M_1 -> M_4;
        M_4 -> M_8;
        M_8 -> M_11;
        M_2 -> M_5;
        M_5 -> M_9;
        M_3 -> M_6;
        M_6 -> M_10;
    }
    subgraph {
        edge [dir=back]
        M_1 -> M_2;
        M_2 -> M_4;
        M_1 -> M_3;
        M_3 -> M_4;
        M_4 -> M_5;
        M_4 -> M_6;
        M_5 -> M_8;
        M_6 -> M_8;
        M_4 -> M_7;
        M_7 -> M_8;
        M_8 -> M_9;
        M_8 -> M_10;
        M_10 -> M_11;
        M_9 -> M_11;
    }
}

gives

enter image description here

By adding an invisible dummy node and setting ranksep, nodesep and spline you can do a little prettyprinting.

digraph g
{
    rankdir=RL
    ranksep=0.5
    nodesep=0.5
    splines=line
    node [shape = record, height=0.1];
    Dummy [style=invisible];
    subgraph {
        node [group=2]
        M_2; M_5; M_9;
    }
    subgraph {
        node [group=1]
        M_1; M_4; M_8; M_11;
    }
    subgraph {
        node [group=3]
        M_3; M_6; M_10;
    }
    M_7;
    subgraph {
        edge [style=dotted]
        M_1 -> M_4;
        M_4 -> M_8;
        M_8 -> M_11;
        M_2 -> M_5;
        M_5 -> M_9;
        M_3 -> M_6;
        M_6 -> M_10;
    }
    subgraph {
        edge [dir=back]
        M_1 -> M_2;
        M_2 -> M_4;
        M_1 -> M_3;
        M_3 -> M_4;
        M_4 -> M_5;
        M_4 -> M_6;
        M_5 -> M_8;
        M_6 -> M_8;
        M_4 -> M_7;
        M_7 -> M_8;
        M_8 -> M_9;
        M_8 -> M_10;
        M_10 -> M_11;
        M_9 -> M_11;
    }
    subgraph {
        edge [dir=none style=invisible]
        M_4 -> Dummy;
        Dummy -> M_8;
    }
}

gives

enter image description here

Upvotes: 4

Related Questions