Search code examples
visualizationgraphvizdotsubgraph

Graphviz subgraph layout


I have a graph with 3 clusters. Main graph has all blue edges. Cluster 1 has all green edges and cluster 2 has all red edges shown as below.

        graph [bb="0,0,414,258.8",
                layout=dot,
                rankdir=LR,
                splines=ortho
        ];
        node [label="\N",
                shape=ellipse
        ];
        edge [color=black,
                weight=10
        ];
        
        0 [shape=rectangle]
        1 [shape=rectangle]
        0 -> 1 [color=blue, weight=10, label=S0]
        2 [shape=rectangle]
        1 -> 2 [color=blue, weight=10, label=S1]
        5 [shape=rectangle]
        2 -> 5 [color=blue, weight=100, label=S4]
        3 [shape=rectangle]
        2 -> 3 [label=S5]
        4 [shape=rectangle]
        2 -> 4 [label=S4]
        
        subgraph {
            graph [rankdir=RL]
            edge[weight=1]
            11 [shape=rectangle]
            2 -> 11 [color=green, xlabel=M1]
            10 [shape=rectangle]
            11 -> 10 [color=green, xlabel=M2]
            10 -> 11 [color=green, xlabel=M3]
            11 -> 2 [color=green, xlabel=M4]
        }
        
        subgraph {
            graph [rankdir=LR]
            edge[weight=8]
            12 [shape=rectangle]
            2 -> 12 [color=red, weight=10, xlabel=M5]
            12 -> 5 [color=red, xlabel=M6]
            5 -> 12 [color=red, xlabel=M7]
            12 -> 2 [color=red, xlabel=M8]
        }
}

This gives me this graph! enter image description here

How do i align all the red edges to bottom left and green edges to the bottom right of main graph like below.

enter image description here

Graphivz editor link -> here


Solution

  • Changes:

    • constraint=false to fix ranking (left-right positioning, in this case)
    • group= to align 0 1 2 5
    • reordered node & edge declarations to get 3 and 4 above 5 (Graphviz "magic", input command sequencing makes a difference)
    • commented out unnecessary attributes
     digraph {
            graph [// bb="0,0,414,258.8",  // dot ignores bb
                    layout=dot,
                    rankdir=LR,
                    splines=ortho
            ];
            node [label="\N",       // already default
                    shape=ellipse   // already default, why not just set to rect?
            ];
            edge [color=black,      // already default
                    XYZweight=10    // effectively commented out all weight references
            ];
            // use group to align 0 1 2 5
            0 [shape=rectangle group=123]
            1 [shape=rectangle group=123]
            2 [shape=rectangle group=123]
            3 [shape=rectangle]
            4 [shape=rectangle]
            5 [shape=rectangle group=123]
            0 -> 1 [color=blue, XYZweight=10, label=S0]
            1 -> 2 [color=blue, XYZweight=10, label=S1]
            2 -> 5 [color=blue, XYZweight=100, label=S4]
            2 -> 3 [label=S5]
            2 -> 4 [label=S4]
            
            subgraph {
                //graph [rankdir=RL]    // rankdir only applies to root graph
                edge[XYZweight=1]
                11 [shape=rectangle]
                2 -> 11 [constraint=false color=green, xlabel=M1]
                10 [shape=rectangle]
                11 -> 10 [ constraint=false color=green, xlabel=M2]
                10 -> 11 [color=green, xlabel=M3]
                11 -> 2  [color=green, xlabel=M4]
            }
            
            subgraph {
                //graph [rankdir=LR]    // rankdir only applies to root graph
                edge[XYZweight=8]
                12 [shape=rectangle]
                2 -> 12 [color=red, XYZweight=10, xlabel=M5]
                12 -> 5 [ constraint=false color=red, xlabel=M6]
                5 -> 12 [ constraint=false color=red, xlabel=M7]
                12 -> 2 [color=red, xlabel=M8]
            }
    }
    

    Giving:
    enter image description here