Compacting a digraph in Graphviz using Dot Language - graphviz

I'm trying to achieve a visualization of a specific graph (a Cayley graph of a symmetric permutation group) as the one done here but using Graphviz 2.28 with Dot.
(source: euclideanspace.com)
digraph cayley {
i -> x [color=red];
i -> y [color=blue];
x -> xx [color=red];
x -> xy [color=blue];
y -> yx [color=red];
y -> yy [color=blue];
xx -> xxx [color=red];
xx -> xxy [color=blue];
xy -> xyx [color=red];
xy -> xyy [color=blue];
yx -> yxx [color=red];
yx -> xyx [color=blue];
yy -> yyx [color=red];
yy -> yyy [color=blue];
xxx -> i [color=red];
xxx -> xxxy [color=blue];
xxy -> xxyx [color=red];
xxy -> xxyy [color=blue];
xyx -> xyxx [color=red];
xyx -> xxyx [color=blue];
xyy -> yy [color=red];
xyy -> xyyy [color=blue];
yxx -> yxxx [color=red];
yxx -> xx [color=blue];
yyx -> xxyy [color=red];
yyx -> xyxx [color=blue];
yyy -> yyyx [color=red];
yyy -> i [color=blue];
xxxy -> xxxyx [color=red];
xxxy -> yyx [color=blue];
xxyx -> yyy [color=red];
xxyx -> xxxyx [color=blue];
xxyy -> xyy [color=red];
xxyy -> yxx [color=blue];
xyxx -> xyxxx [color=red];
xyxx -> xxx [color=blue];
xyyy -> xyyyx [color=red];
xyyy -> x [color=blue];
yxxx -> y [color=red];
yxxx -> xyyyx [color=blue];
yyyx -> xxy [color=red];
yyyx -> xyxxx [color=blue];
xxxyx -> xyyy [color=red];
xxxyx -> yx [color=blue];
xyxxx -> xy [color=red];
xyxxx -> yxxx [color=blue];
xyyyx -> xxxy [color=red];
xyyyx -> yyyx [color=blue];
}
My Dot generates the following layout: which is a pretty huge graph compared with the previous one. Is there any attribute that can compact the graph as close as possible to the first one ?

I modified the codes such as graph, node and edge default attributes to make the layout as compacted as possible. Maybe there is a more perfect approach. By the way, the node i is located at the left but not right.
digraph cayley {
graph[rankdir=LR, center=true, margin=0.2, nodesep=0.1, ranksep=0.3]
node[shape=circle, fontname="Courier-Bold", fontsize=10, width=0.4, height=0.4, fixedsize=true]
edge[arrowsize=0.6, arrowhead=vee]
i -> x [color=red];
i -> y [color=blue];
x -> xx [color=red];
x -> xy [color=blue];
y -> yx [color=red];
y -> yy [color=blue];
xx -> xxx [color=red];
xx -> xxy [color=blue];
xy -> xyx [color=red];
xy -> xyy [color=blue];
yx -> yxx [color=red];
yx -> xyx [color=blue];
yy -> yyx [color=red];
yy -> yyy [color=blue];
xxx -> i [color=red];
xxx -> xxxy [color=blue];
xxy -> xxyx [color=red];
xxy -> xxyy [color=blue];
xyx -> xyxx [color=red];
xyx -> xxyx [color=blue];
xyy -> yy [color=red];
xyy -> xyyy [color=blue];
yxx -> yxxx [color=red];
yxx -> xx [color=blue];
yyx -> xxyy [color=red];
yyx -> xyxx [color=blue];
yyy -> yyyx [color=red];
yyy -> i [color=blue];
xxxy -> xxxyx [color=red];
xxxy -> yyx [color=blue];
xxyx -> yyy [color=red];
xxyx -> xxxyx [color=blue];
xxyy -> xyy [color=red];
xxyy -> yxx [color=blue];
xyxx -> xyxxx [color=red];
xyxx -> xxx [color=blue];
xyyy -> xyyyx [color=red];
xyyy -> x [color=blue];
yxxx -> y [color=red];
yxxx -> xyyyx [color=blue];
yyyx -> xxy [color=red];
yyyx -> xyxxx [color=blue];
xxxyx -> xyyy [color=red];
xxxyx -> yx [color=blue];
xyxxx -> xy [color=red];
xyxxx -> yxxx [color=blue];
xyyyx -> xxxy [color=red];
xyyyx -> yyyx [color=blue];
{ rank=same; x; y }
{ rank=same; xx; xy; yx; yy }
{ rank=same; xxx; xxy; xyx; xyy; yxx; yyx; yyy }
{ rank=same; xxxy; xxyx; xxyy; xyxx; xyyy; yxxx; yyyx }
{ rank=same; xxxyx; xyxxx; xyyyx }
}
The image is shown as following.

Related

how to avoid the overlap of the edge of graphviz

I have Graphviz as below:
digraph G {
node [fontname = "font-awesome"]; edge [dir=none];
A [label="A"];
B [label="B"];
c_A_B [shape=diamond];
{rank=same; A -> c_A_B -> B};
C [label="C"];
L1_0 [shape=circle,label="",height=0.01,width=0.01];
L1_0->C;
D [label="D"];
L1_1 [shape=circle,label="",height=0.01,width=0.01];
L1_1->D;
E [label="E"];
L1_2 [shape=circle,label="",height=0.01,width=0.01];
L1_2->E;
{rank=same; L1_0->L1_1->L1_2};
{rank=same; C; D; E;};
c_A_B->L1_1;
F [label="F"];
c_E_F [shape=diamond];
{rank=same; E->c_E_F->F};
L2_0 [shape=circle,label="",height=0.01,width=0.01];
c_E_F->L2_0;
}
which shows the graph as below, can anyone be kind to help me how to avoid the edge overlapping?
I this case in this case a solution for you can be an invisible edge in the form of:
C -> D [style=invis];
so your example would look like:
digraph G {
node [fontname = "font-awesome"]; edge [dir=none];
A [label="A"];
B [label="B"];
c_A_B [shape=diamond];
{rank=same; A -> c_A_B -> B};
C [label="C"];
L1_0 [shape=circle,label="",height=0.01,width=0.01];
L1_0->C;
D [label="D"];
L1_1 [shape=circle,label="",height=0.01,width=0.01];
L1_1->D;
C -> D [style=invis];
E [label="E"];
L1_2 [shape=circle,label="",height=0.01,width=0.01];
L1_2->E;
{rank=same; L1_0->L1_1->L1_2};
{rank=same; C; D; E;};
c_A_B->L1_1;
F [label="F"];
c_E_F [shape=diamond];
{rank=same; E->c_E_F->F};
L2_0 [shape=circle,label="",height=0.01,width=0.01];
c_E_F->L2_0;
}
And the resulting image is:

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;
}

Edge crossing each other

is there a way to eliminate the crossing of edges?
I tried many ways, nothing helped.
digraph graphname {
graph [splines=ortho,];
node [shape=box,];
l;
l_a [shape=diamond,label="",height=0.20,width=0.20];
l_a_s [shape=point];
l_a_i [shape=point];
l_a_ii [shape=point];
l_a -> l_a_s;
{rank=same; a -> l_a -> l}
{rank=same; l_a_i -> l_a_s -> l_a_ii}
l_a_i -> i;
l_a_ii -> ii;
l_c [shape=diamond,label="",height=0.20,width=0.20];
l_c_s [shape=point];
l_c_t [shape=point];
l_c_n [shape=point];
l_c -> l_c_s;
{rank=same; l -> l_c -> c}
{rank=same; l_c_t -> l_c_s -> l_c_n}
l_c_t -> t;
l_c_n -> n;
}
some more details:
All you need to do is to reorganize your node/edge definitions a little bit, no additional edges needed.
for example:
digraph graphname {
graph [splines=ortho,];
node [shape=box,];
a;
l_a [shape=diamond,label="",height=0.20,width=0.20];
l;
l_c [shape=diamond,label="",height=0.20,width=0.20];
c;
{rank=same; a -> l_a -> l -> l_c -> c}
l_a_s [shape=point];
l_c_s [shape=point];
l_a -> l_a_s;
l_c -> l_c_s;
l_a_i [shape=point];
l_a_ii [shape=point];
l_c_t [shape=point];
l_c_n [shape=point];
{rank=same;
l_a_i -> l_a_s -> l_a_ii;
l_c_t -> l_c_s -> l_c_n;}
l_a_i -> i;
l_a_ii -> ii;
l_c_t -> t;
l_c_n -> n;
}
Adding this invisible edge solves your problem:
l_a_i -> l_c_s [constraint=false style=invis]
I can't prove mathematically why this works, but in such situation it usually helps to play with order in which nodes/edges are defined, or try adding invisible adges to nudge the layout in the direction you need

How do I create clusters in dot?

Suppose, I want to make a subcluster between a few nodes in a graph (to somehow denote that these nodes go together for one reason or another for example):
digraph G {
A [group=g1]
{rank = same; B[group=g2]; C[group=g3]}
D [group=g1]
{rank = same; E[group=g2]; F[group=g3]}
A -> B [label="2", weight=2]
A -> C [label="0", style=dashed, weight=2]
B -> C [label="0", style=dashed, weight=2]
B -> D [label="2", style=dashed, weight=2]
C -> D [label="0", weight=2]
D -> E [label="1", style=dashed, weight=2]
D -> F [label="0", weight=2]
E -> F [label="0", weight=2]
F -> A
edge[style=invis];
A -> D
B -> E
C -> F
subgraph cluster_0 {
label = "I want this in its own sub-square"
B->E
B->Asti
style=filled;
color=lightgrey;
node [style=filled,color=white];
edge[style=invis];
}
}
As you can see, I'm only partially successful. That is, asti is in its own greyed-out cluster but the nodes B and E are not.
Can someone please point out how do I place all three nodes E, B and asti in that greyed-out cluster?
Thanks
Use newrank=true to avoid of "unboxing" clusters
digraph G {
newrank=true;
A [group=g1]
{rank = same; B[group=g2]; C[group=g3]}
D [group=g1]
{rank = same; E[group=g2]; F[group=g3]}
A -> B [label="2", weight=2]
A -> C [label="0", style=dashed, weight=2]
B -> C [label="0", style=dashed, weight=2]
B -> D [label="2", style=dashed, weight=2]
C -> D [label="0", weight=2]
D -> E [label="1", style=dashed, weight=2]
D -> F [label="0", weight=2]
E -> F [label="0", weight=2]
F -> A
edge[style=invis];
A -> D
B -> E
C -> F
subgraph cluster_0 {
label = "I want this in its own sub-square"
B->E
B->Asti
style=filled;
color=lightgrey;
node [style=filled,color=white];
edge[style=invis];
}
}

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

Resources