Subgraph layout in graphviz - graphviz

I have code to display two subgraphs:
graph {
rankdir=LR;
subgraph cluster01 {
label="t=0"
a0 [label="A"];
a1 [label="B"];
a2 [label="C"];
a5 [label="E"];
a0 -- a1;
a1 -- a2 ;
a2 -- a0;
};
subgraph cluster02
{
label="t=10"
b0 [label="A"];
b5 [label="E"];
b1 [label="B"];
b2 [label="C"];
b0 -- b1;
b2 -- b5;
};
a0--b0 [style=dotted];
a1--b1 [style=dotted];
a2--b2 [style=dotted];
a5--b5 [style=dotted];
}
This code displays two subgraphs like this:
But I want to have it like this:
I hope someone will help me fix the "rankdir" to get it done.

The following was achieved by using invisible edges and constraint=false on some edges:
graph {
rankdir=LR;
subgraph cluster01 {
label="t=0";
a0 [label="A"];
a1 [label="B"];
a2 [label="C"];
a5 [label="E"];
a0 -- a1;
a1 -- a2;
a2 -- a5 [style=invis];
a2 -- a0 [constraint=false];
};
subgraph cluster02
{
label="t=10"
b0 [label="A"];
b5 [label="E"];
b1 [label="B"];
b2 [label="C"];
b0 -- b1;
b1 -- b2 [style=invis];
b2 -- b5;
};
edge[constraint=false];
a0--b0 [style=dotted];
a1--b1 [style=dotted];
a2--b2 [style=dotted];
a5--b5 [style=dotted];
}

Related

Align nodes of subgraph with another subgraph nodes

How do I align nodes with each other between subgraphs?
In the example, I would like all the 0 nodes aligned vertically as well as the 1, 2, 3 and 4 nodes. It would be good if all the right edges of subgraphs were extended as necessary to align too.
digraph AlignWhenMissing {
rankdir=LR;
node [shape=box]
subgraph clusterA {label = "A Shift a4 along (no a3)";
a0 -> a1;
a1 -> a2;
a2 -> a4;
}
subgraph clusterB {label = "B Shift b2 above a2";
b0 -> b2;
b2 -> b3;
}
subgraph clusterC {label = "C Shift c3 above b3";
c0 -> c3;
}
A -> a0[lhead=clusterA];
B -> b0[lhead=clusterB];
C -> c0[lhead=clusterC];
a0 -> b0[constraint=false];
b3 -> c3[constraint=false];
a2 -> b2[constraint=false];
}
The minlen attribute (https://graphviz.org/docs/attrs/minlen/) applies to edges to lengthen them (i.e. to push them "out" by N ranks).
Then added invisible nodes and edges to increase cluster dimension.
digraph AlignWhenMissing {
rankdir=LR;
node [shape=box]
subgraph clusterA {label = "A Shift a4 along (no a3)";
a0 -> a1;
a1 -> a2;
a2 -> a4 [minlen=2];
}
subgraph clusterB {label = "B Shift b2 above a2";
b0 -> b2 [minlen=2]
b2 -> b3;
b4 [style=invis]
b3 -> b4 [style=invis]
}
subgraph clusterC {label = "C Shift c3 above b3";
c0 -> c3 [minlen=3];
c4 [style=invis]
c3 -> c4 [style=invis]
}
A -> a0[lhead=clusterA];
B -> b0[lhead=clusterB];
C -> c0[lhead=clusterC];
a0 -> b0[constraint=false];
b3 -> c3[constraint=false];
a2 -> b2[constraint=false];
}
Giving:

Maintain horizontal ordering of nodes in Graphviz

I have the following the dot file contents:
digraph G {
start -> {a0, b0} -> end;
start -> c0 -> c1 -> c2 -> end;
start -> d0 -> d1 -> d2 -> end;
start -> {e0, f0} -> end;
subgraph cluster_test {
{
rank = same;
a0; b0; c0; d0; e0; f0;
}
{
rank = same;
c1; d1;
}
{
rank = same;
c2; d2;
}
}
}
The resulting graph is as follows:
What I want is for the ordering of level 0 nodes to be maintained, i.e, I want a0, b0 to come before c0, d0 in the horizontal direction.
How do I achieve this?
Empty nodes, edges with weight and explicit ordering of the top row in the cluster helps. See code below with annotations:
digraph so
{
// we define all nodes in the beginning, before edges and clusters
// may not be essential but I think it's good practice
start
a0 b0 c0 d0 e0 f0
c1 d1
c2 d2
end
// we define "empty" nodes that can be used to route the edges
node[ shape = point, height = 0 ];
ax bx ex fx
subgraph cluster_test
{
// we need to keep explicit order of the top nodes in the cluster
{ rank = same; a0 -> b0 -> c0 -> d0 -> e0 -> f0[ style = invis ] }
// the original layout in the cluster, empty nodes added at the bottom
{ rank = same; c1 d1 }
{ rank = same; ax bx c2 d2 ex fx }
c0 -> c1 -> c2;
d0 -> d1 -> d2;
// routing through invisible nodes keeps the position of all other nodes
// edges with no arrowheads, strong weight to keep it vertical
edge[ dir = none, weight = 10 ]
a0 -> ax;
b0 -> bx;
e0 -> ex;
f0 -> fx;
}
// connecting to the start and end node, normal edges again
edge[ weight = 1, dir = forw ];
start -> { a0 b0 c0 d0 e0 f0 }
{ ax bx c2 d2 ex fx } -> end;
}
which gives you

Vertical alignment of nodes in graphviz

I am trying to make a graph where {C1;C2} are aligned vertically. Same with {A;B;C} and {E1;E2;E3}
Here is my code so far:
digraph G{
rankdir="LR";
S -> C1 [label="150"];
S -> C2 [label="130"];
C1 -> A [label="70"];
C1 -> B [label="80"];
C2 -> B [label="60"];
C2 -> C [label="70"];
C -> B [label="10"];
A -> E1 [label="70"];
B -> E1 [label="80"];
B -> D [label="70"];
C -> E3 [label="60"];
D -> E1 [label="40"];
D -> E2 [label="0"];
D -> E3 [label="30"];
E1 -> t [label="190"];
E2 -> t [label="0"];
E3 -> t [label="90"];
}
Here is the result so far:
{ rank = same; } is your friend. I have added invisible edges between A, B and C to keep them tighter together, and reversed one of your connections in orde to keep A over B over C etc.
digraph G
{
rankdir="LR";
{ rank = same; C1 C2 }
{ rank = same; A -> B -> C[ style = invis ] }
{ rank = same; E1 E2 E3 }
S -> C1 [label="150"];
S -> C2 [label="130"];
C1 -> A [label="70"];
C1 -> B [label="80"];
C2 -> B [label="60"];
C2 -> C [label="70"];
B -> C [dir = back, label="10"]; // to keep B above C
A -> E1 [label="70"];
B -> E1 [label="80"];
B -> D [label="70"];
C -> E3 [label="60"];
D -> E1 [label="40"];
D -> E2 [label="0"];
D -> E3 [label="30"];
E1 -> t [label="190"];
E2 -> t [label="0"];
E3 -> t [label="90"];
}
yields

How can I prevent graphviz from drawing edges over labels?

If I run graphviz on this digraph:
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0; a1; a2; a3;
label = "sources";
}
subgraph cluster_1 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
b0; b1; b2; b3;
label = "intermediaries";
}
a0 -> b0; a1 -> b0;
a0 -> b1; a1 -> b1;
a2 -> b2; b0 -> b2;
b1 -> b2; a3 -> b3;
b0 -> b3; b1 -> b3;
}
I get
with many edges intersecting the "intermediaries" label. How do I get graphviz to make edges avoid labels?
As a workaround:
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0; a1; a2; a3;
label = "sources";
}
subgraph cluster_1 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
nodelabel [label="intermediaries"; style=filled; color=lightgrey]
nodelabel -> b1 [style=invis];
nodelabel -> b0 [style=invis];
b0; b1; b2; b3;
}
a0 -> b0; a1 -> b0;
a0 -> b1; a1 -> b1;
a2 -> b2; b0 -> b2;
b1 -> b2; a3 -> b3;
b0 -> b3; b1 -> b3;
}
produce:

How to left-align a node in Graphviz?

I am trying to display digital circuit netlist with graphviz.
I am resorting to :
record shapes to represent input/output ports.
rankdir=LR to suggest a left to right alignment
The following code works fine. However, during layout, some inputs (here "i3") can be misaligned : I would expect i3 to be left-aligned, as for i1 and i2.
How can I do that ?
digraph G {
graph [rankdir = LR];
node[shape=record];
c1[ label="{ {<i1>i1|<i2>i2}| c1 | {<f>f} }"];
c2[ label="{ {<i0>i0}| c2 | {<out_0>out_0} }"];
c3[ label="{ {<i0>i0}| c3 | {<out_0>out_0} }"];
c4[ label="{ {<i0>i0|<i1>i1}| c4 | {<out_0>out_0} }"];
i1; i2; i3; f; i1 -> c2:i0[ label="w(1)"];
i2 -> c3:i0[ label="w(2)"];
i3 -> c4:i1[ label="w(4)"];
c1:f -> c4:i0[label="w(3)"];
c2:out_0 -> c1:i1[label="w(5)"];
c3:out_0 -> c1:i2[label="w(6)"];
c4:out_0 -> f[label="w(7)"];
}
Just specify that i1, i2 and i3 share the same rank:
digraph G {
graph [rankdir = LR];
node[shape=record];
c1[ label="{ {<i1>i1|<i2>i2}| c1 | {<f>f} }"];
c2[ label="{ {<i0>i0}| c2 | {<out_0>out_0} }"];
c3[ label="{ {<i0>i0}| c3 | {<out_0>out_0} }"];
c4[ label="{ {<i0>i0|<i1>i1}| c4 | {<out_0>out_0} }"];
i1; i2; i3; f; i1 -> c2:i0[ label="w(1)"];
i2 -> c3:i0[ label="w(2)"];
i3 -> c4:i1[ label="w(4)"];
c1:f -> c4:i0[label="w(3)"];
c2:out_0 -> c1:i1[label="w(5)"];
c3:out_0 -> c1:i2[label="w(6)"];
c4:out_0 -> f[label="w(7)"];
{rank=same; i1; i2; i3}
}

Resources