Search code examples
plotgraphvizdot

Alignment of subgraphs and nodes in Graphviz


I'm working on a dot graph with two clusters. I would like to achieve the following:

  1. Clusters horizontally aligned in the middle of the graph space.
  2. Nodes horizontally aligned within clusters.
  3. Edges from P nodes to E nodes as straight as possible.

This is what I tried so far:

digraph G {
    compound=true;
    rankdir=LR;
    
    subgraph cluster_states {
        style=invis;
        rank=same P1 P2;
        P1 [fillcolor="#80B1D3", shape=ellipse, style=filled, group=a];
        P2 [fillcolor="#80B1D3", shape=ellipse, style=filled, group=a];
    }
    
    subgraph cluster_symbols {
        style=invis;
        rank=same E1 E2 E3;
        E1 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b];
        E2 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b];
        E3 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b];
    }
    
    P1 -> P1  [color="#8d8d8d", label=" 0.4 ", style=filled, weight=0.4, constraint=true];
    P1 -> P2  [color="#5e5e5e", label=" 0.6 ", style=filled, weight=0.6, constraint=true];
    P2 -> P1  [color="#464646", label=" 0.7 ", style=filled, weight=0.7, constraint=true];
    P2 -> P2  [color="#a5a5a5", label=" 0.3 ", style=filled, weight=0.3, constraint=true];
    P1 -> E1  [color="#d4d4d4", label=" 0.1 ", style=dashed, weight=0.1, constraint=false];
    P1 -> E2  [color="#757575", label=" 0.5 ", style=dashed, weight=0.5, constraint=false];
    P1 -> E3  [color="#8d8d8d", label=" 0.4 ", style=dashed, weight=0.4, constraint=false];
    P2 -> E1  [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=0.2, constraint=false];
    P2 -> E2  [color="#5e5e5e", label=" 0.6 ", style=dashed, weight=0.6, constraint=false];
    P2 -> E3  [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=0.2, constraint=false];
}

And this is the result, obviously far from what I'm looking for:

enter image description here

This is the result I would like to obtain (approximately... sorry, but I'm really bad at drawing):

enter image description here


Solution

    • removed all cluster references
    • changed rankdir
    • changed splines to straight lines
    • increased nodesep and ranksep to spread things out
    • created explicit subgraphs to set rank=same
    • (just noticed) group attributes unneeded
    • removed other unneeded attributes
    • changed labels to xlabels (should not be needed, but caused funky result with splines=line)
    • changed two xlabels back to labels (for self-loops)
    • added explicit ports to looping edges
    • added \n to some labels to reposition

    Giving:
    enter image description here

    digraph G {
      //     compound=true;  not used
      //  rankdir=LR;  // TB (default)
      splines=line  // straight lines, as shown
      nodesep=1.25  // inches
      ranksep=.85   // inches
    
            {rank=same P1 P2;  // needs to be within explicit subgraph
            P1 [fillcolor="#80B1D3", shape=ellipse, style=filled]
            P2 [fillcolor="#80B1D3", shape=ellipse, style=filled]
        }
        
            { rank=same E1 E2 E3; // needs to be within explicit subgraph
            E1 [fillcolor="#E0E0E0", shape=hexagon, style=filled]
            E2 [fillcolor="#E0E0E0", shape=hexagon, style=filled]
            E3 [fillcolor="#E0E0E0", shape=hexagon, style=filled]
        }
        
        P1:nw -> P1:ne  [color="#8d8d8d", label="0.4", style=filled]  // ports
        P1 -> P2  [color="#5e5e5e", xlabel=" 0.6 ", style=filled]
        P2 -> P1  [color="#464646", xlabel=" 0.7 ", style=filled]
        P2:nw -> P2:ne  [color="#a5a5a5", label="0.3", style=filled]  // ports
        P1 -> E1  [color="#d4d4d4", xlabel="\n 0.1 ", style=dashed]
        P1 -> E2  [color="#757575", xlabel="\n 0.5 ", style=dashed]
        P1 -> E3  [color="#8d8d8d", xlabel="\n 0.4 ", style=dashed]
        P2 -> E1  [color="#bcbcbc", xlabel="\n 0.2 ", style=dashed]
        P2 -> E2  [color="#5e5e5e", xlabel="\n 0.6 ", style=dashed]
        P2 -> E3  [color="#bcbcbc", xlabel="\n 0.2 ", style=dashed]
    }