How can I prevent graphviz from drawing edges over labels? - graphviz

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:

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:

How to change the order of same rank nodes in Graphviz?

I'd like the column a ... i to be the first column from the left and a1 ... f1 the first column from the right. I tried to setup same rank, different weights, but with no luck. How can I control the order of columns?
digraph G {
newrank = true;
node [shape=record, style="rounded,filled", color="#5F6368", fillcolor="#F7F7F7", fontname="Arial", fontsize=10];
graph [fontname = "Arial"]; edge [fontname = "Arial"];
style = "dashed";
subgraph cluster0 {
color="#34A853";
a; a1; b; b1; c; c1; d; d1;
}
subgraph cluster1 {
color="#EA4335";
e1; f1;
subgraph cluster2 {
color="#FBBC05";
e; f; g; h; i;
}
}
a -> b -> c -> d [color="#34A853"];
a1 -> b1 -> c1 -> d1 [color="#4285F4"];
edge[style=invis];
{rank="same"; a -> a1 [constraint=false]}
{rank="same"; b -> b1 [constraint=false]}
{rank="same"; c -> c1 [constraint=false]}
{rank="same"; d -> d1 [constraint=false]}
{rank="same"; e -> e1 [constraint=false]}
{rank="same"; f -> f1 [constraint=false]}
d -> e -> f -> g -> h -> i;
d1 -> e1 -> f1;
}

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

Clusters squeeze nodes in GraphViz

I have several related sub-graphs that I want to draw together in GraphViz. When I draw simple nodes it looks quite pretty:
Source:
digraph {
rankdir=LR;
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
As the nodes in the same level across the several sub-graphs are related, I want to group them and give it a label.
I tried to do it using clusters, but it "squeezes" the nodes:
Source:
digraph {
rankdir=LR;
subgraph cluster_level1 {
label = "Level 1";
style=filled;
color=lightgrey;
A1;
B1;
}
subgraph cluster_level2 {
label = "Level 2";
style=filled;
color=lightgrey;
A21;
A22;
A23;
A24;
B21;
B22;
B23;
B24;
}
subgraph cluster_level3 {
label = "Level 3";
style=filled;
color=lightgrey;
A31;
A32;
B31;
B32;
B33;
}
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
With just two sub-graphs, it's bad, but still not horrible. However, if I add more sub-graphs, it becomes uglier and uglier.
Is there a way to group nodes with some shadowing and labels, while keeping the original nodes layout using GraphViz?
This is probably not a good answer since it implies a lot of trial and error but at least you get what you want (I guess) with invisible nodes:
digraph {
rankdir=LR;
subgraph cluster_level1 {
label = "Level 1";
style=filled;
color=lightgrey;
A01[ style = invis ];
A1;
A02[ style = invis ];
A03[ style = invis ];
A06[ style = invis ];
A05[ style = invis ];
B1;
A04[ style = invis ];
}
subgraph cluster_level2 {
label = "Level 2";
style=filled;
color=lightgrey;
A21;
A22;
A23;
A24;
B21;
B22;
B23;
B24;
}
subgraph cluster_level3 {
label = "Level 3";
style=filled;
color=lightgrey;
A07[ style = invis ];
A31;
A32;
A08[ style = invis ];
B31;
B32;
B33;
A01[ style = invis ];
A09[ style = invis ];
}
A1 -> A21;
A1 -> A22;
A1 -> A23;
A1 -> A24;
B1 -> B21;
B1 -> B22;
B1 -> B23;
B1 -> B24;
A21 -> A31;
A22 -> A31;
A23 -> A31;
A23 -> A32;
B21 -> B31;
B21 -> B32;
B22 -> B32;
B21 -> B33;
B23 -> B33;
}
yields

Subgraph layout in 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];
}

Resources