How can I get dot to draw connected subgraphs side by side? - graphviz

This is what the generated graph looks currently:
And here is the code for this:
digraph {
rankdir=TB;
subgraph cluster01 {
label="1.fázis"
aSTART;
node [shape = doublecircle]; a001;
node [shape = ellipse];
aSTART -> a0 [ penwidth = 3 label = "0" ];
a0 -> a00 [ penwidth = 3 label = "0" ];
a00 -> a001 [ penwidth = 3 label = "1" ];
a0 -> aSTART [ label = "1" ];
a00 -> a00 [ label = "0" ];
a001 -> a0 [ label = "0"];
a001 -> aSTART [ label = "1"];
aSTART -> aSTART [ label = "1"];
}
subgraph cluster02
{
label="2.fázis"
bSTART; b1; b11;
node [shape = doublecircle]; b111;
node [shape = ellipse];
bSTART -> b1 [ penwidth = 3 label = "1" ];
b1 -> b11 [ penwidth = 3 label = "1" ];
b11 -> b111 [ penwidth = 3 label = "1" ];
b1 -> bSTART [ label = "0" ];
b11 -> bSTART [ label = "0" ];
b111 -> bSTART [ label = "0"];
bSTART -> bSTART [ label = "0"];
b111 -> b111 [label = "1"];
}
subgraph cluster03
{
label="3.fázis";
cSTART; c0; c1; c01; c10;
node [shape = doublecircle]; c010; c100;
node [shape = ellipse];
cSTART -> c0 [ penwidth = 3 label = "0" ];
c0 -> c01 [ label = "1" ];
c01 -> c010 [ penwidth = 3 label = "0" ];
cSTART -> c1 [ label = "1" ];
c1 -> c10 [ penwidth = 3 label = "0" ];
c10 -> c100 [ label = "0" ];
c0 -> c1 [ penwidth = 3 label = "1" ];
c01 -> c1 [ label = "1" ];
c1 -> c1 [label = "1"];
c10 -> c01 [ penwidth = 3 label = "1"];
c010 -> c100 [penwidth = 3 label = "0"];
c010 -> c01 [label = "1"];
c100 -> c01 [label = "1"];
c100 -> c0 [label = "0"];
}
a001 -> b1 [color = "red" style = "dashed"];
b111 -> c1 [color = "red" style = "dashed"];
}
If I remove the 2 red lines, then it lines up the way I want it to:
How could I make it line up like this and have the two red lines at the same time?

You can add
{
rank=same;
aSTART;
bSTART
cSTART;
}
After your subgraph cluster03. Dot will yield you a warning but draw the way yo want:
D:\Code\funfunfun>dot -Tpng -oso1.png -Gcharset=latin1 so1.dot
Warning: aSTART was already in a rankset, ignored in cluster _anonymous_0
Warning: bSTART was already in a rankset, ignored in cluster _anonymous_0
Warning: cSTART was already in a rankset, ignored in cluster _anonymous_0
Patched graph available here

You should use the constraint=false attribute on the two red edges.
If false, the edge is not used in ranking the nodes.

Related

Centers node in a cluster

I try to draw multiple finite state diagram in graphviz in only one diagram
For now i have this :
digraph D {
rankdir = LR;
node [shape = circle]
subgraph automaton_1 {
invis [shape = point style = invis]
0 [label =<S<SUB>0</SUB>>]
1 [label =<S<SUB>1</SUB>>]
2 [label =<S<SUB>2</SUB>>]
3 [label =<S<SUB>3</SUB>>]
4 [label =<S<SUB>4</SUB>>]
5 [label =<S<SUB>5</SUB>> peripheries = 2]
}
invis -> 0
0 -> 1[label = "a"]
1 -> 2[label = "b"]
0 -> 3[label = "b"]
3 -> 4[label = "c"]
2 -> 5[label = "d"]
4 -> 5[label = "d"]
subgraph automaton_2 {
b_invis [shape = point style = invis]
b_0 [label =<S<SUB>0</SUB>'>]
b_1 [label =<S<SUB>1</SUB>'>]
b_2 [label =<S<SUB>2</SUB>'>]
b_3 [label =<S<SUB>3</SUB>'>]
b_4 [label =<S<SUB>4</SUB>'>]
b_5 [label =<S<SUB>5</SUB>'> peripheries = 2]
}
b_invis -> b_0
b_0 -> b_1[label = "a"]
b_1 -> b_2[label = "b"]
b_0 -> b_3[label = "b"]
b_3 -> b_4[label = "c"]
b_2 -> b_5[label = "d"]
b_4 -> b_5[label = "d"]
invis -> b_invis[constraint=false, style=invis]
}
which give this result : image 1
But i want to have two independently aligned diagram, aligned like this : image 2
You can turn your subgraphs into actual clusters by adding cluster_ to their names. Inside clusters nodes from each of the subgraphs won't be affected by each other.
Here's the corrected code and the result (note that I've also added peripheries=0 for each cluster to remove borders:
digraph D {
rankdir = LR;
node [shape = circle]
subgraph cluster_automaton_1 {
peripheries=0
invis [shape = point style = invis]
0 [label =<S<SUB>0</SUB>>]
1 [label =<S<SUB>1</SUB>>]
2 [label =<S<SUB>2</SUB>>]
3 [label =<S<SUB>3</SUB>>]
4 [label =<S<SUB>4</SUB>>]
5 [label =<S<SUB>5</SUB>> peripheries = 2]
}
invis -> 0
0 -> 1[label = "a"]
1 -> 2[label = "b"]
0 -> 3[label = "b"]
3 -> 4[label = "c"]
2 -> 5[label = "d"]
4 -> 5[label = "d"]
subgraph cluster_automaton_2 {
peripheries=0
b_invis [shape = point style = invis]
b_0 [label =<S<SUB>0</SUB>'>]
b_1 [label =<S<SUB>1</SUB>'>]
b_2 [label =<S<SUB>2</SUB>'>]
b_3 [label =<S<SUB>3</SUB>'>]
b_4 [label =<S<SUB>4</SUB>'>]
b_5 [label =<S<SUB>5</SUB>'> peripheries = 2]
}
b_invis -> b_0
b_0 -> b_1[label = "a"]
b_1 -> b_2[label = "b"]
b_0 -> b_3[label = "b"]
b_3 -> b_4[label = "c"]
b_2 -> b_5[label = "d"]
b_4 -> b_5[label = "d"]
invis -> b_invis[constraint=false, style=invis]
}

How to modify arrow path?

How to have arrow 2 have the same shape as arrow 1?
digraph {
rankdir=LR
label = "Lý thuyết ý định hành động";
labelloc = t
labeljust = r
fontsize = 20
fontname = Lato
overlap=false;
a [ label = "Thái độ của\nbản thân đối\nvới hành động" ]
b [ label = "Cảm nhận về\nthế nào là\nchuẩn mực" group=g1]
c [ label = "Cảm nhận về\nkhả năng đạt\nđược kết quả" ]
d [ label = "Có ý định hành động" group=g1 style=rounded shape=polygon ]
e [ label = "Thực sự hành động" group=g1 style=rounded shape=box3d ]
{ rank=same; a, b, c }
a:w -> b:w [ label="" dir=both]
a:w -> c:w [ label=" " dir=both]
b:w -> c:w [ label="" dir=both]
a:e -> d:n [ label="1" ]
b:e -> d:w
c:e -> d:s [ label="2" ]
d -> e
c -> e:s [style=dashed dir=none]
}
By the way, the left arrows can only be that symmetric when I put empty labels to them. Is there any explanation for this?

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

Adding labels under subgraphs in Graphviz

I use the following code to produce a graph using dot in Graphviz. I have manually included the coordinates of nodes, as I require four disjoint subgraphs placed adjacent to one another, as in the picture.
I would love to add labels under each of the subgraphs: $G_0$, $G_1$, etc. Adding label under subgraph creates a box and ignores my coordinates alignment. Is there any other way, like placing arbitrary text at specified coordinates? I use "dot -Teps -Kfdp -n trees -o t.eps" for compilation.
digraph Trees {
node [shape=circle, style="filled", fixedsize=true,width=0.6]; 0; 1;2; 3;4; 5;6; 7; 8;9;10;11;12;13;14;15;
0[pos = "0,1!"]
1[fillcolor=red, pos = "-1,2!"]
2[pos = "1,2!"]
3 [pos = "0,-0.5!"]
5[label=1, fillcolor=red, pos = "2,2!"]
4[label=0, fillcolor=red, pos = "3,1!"]
6[label=2, pos = "4,2!"]
7[label=3, pos = "3, -0.5!"]
9[label=1, fillcolor=red, pos = "5,2!"]
8[label=0, fillcolor=red, pos = "6,1!"]
10[label=2, pos = "7,2!"]
11[label=3, fillcolor=red, pos = "6, -0.5!"]
12[label=1, fillcolor=red, pos = "8,2!"]
13[label=0, fillcolor=green, pos = "9,1!"]
14[label=2, pos = "10, 2!"]
15[label=3, fillcolor=green, pos = "9, -0.5!"]
overlap=false;
fontsize=10;
subgraph 1{
edge [dir=none] 1->0 2->0 3->0;
}
subgraph 2{
edge [color=red] 5->4;
edge[color=black, dir=none] 6->4 7->4;
}
subgraph 3{
edge [color=red] 9->8 8->11;
edge [color=black, dir=none] 8->10;
}
subgraph 4{
edge [color=green] 12->13; 13->15;
edge [color=black, dir=none] 13->14;
}
}
The sub-graphs can be made disjoint using clusters and the dot layout engine. The same approach will also permit the introduction of cluster labels. They can be placed at the bottom of the cluster as required without creating dummy nodes.
This way, no absolute positions are required, and, the layout is automatically generated even if other nodes are added. The exact position of the nodes change, but the graphs remain topologically unchanged.
digraph Trees { node [shape = circle, style = "filled", fixedsize = true, width=0.4];
edge [dir = none];
layout = dot; overlap = false; fontsize = 10;
graph [labelloc = "b", penwidth = 0];
{ node [fillcolor = "red"];
1; 5 [label = 1]; 4 [label = 0]; 9 [label = 1];
8 [label = 0]; 11 [label = 3]; 12 [label = 1];
}
2; 0; 3; 6 [label = 2]; 7 [label = 3];
10 [label = 2]; 14 [label = 2];
{ node [fillcolor = "green"];
13 [label = 0]; 15 [label = 3];
}
subgraph cluster1{
label = "Subgraph 1";
{ 1; 2; } -> 0 -> 3;
}
subgraph cluster2{
label = "Subgraph 2";
5 -> 4 [color = red, dir = fwd];
6 -> 4 -> 7;
}
subgraph cluster3{
label = "Subgraph 3";
9 -> 8-> 11 [color=red, dir = fwd];
10 -> 8 [color=black];
}
subgraph cluster4{
label = "Subgraph 4";
12 -> 13 -> 15 [color=green, dir = fwd];
14-> 13;
}
}
Instead of using explicit node positions, you may use a simple directed graph combined with some rank constraints, invisible edges and text nodes instead of subgraph labels:
digraph Trees {
fontsize=10;
node [shape=circle, style="filled", fixedsize=true,width=0.6];
{rank=same;
a1[label=1, fillcolor=red];
a2[label=2];
a3[label=1, fillcolor=red];
a4[label=2];
a5[label=1, fillcolor=red];
a6[label=2];
a7[label=1, fillcolor=red];
a8[label=2];
}
node[label=0];
b1;
b2[fillcolor=red];
b3[fillcolor=red];
b4[fillcolor=green];
node[label=3];
c1;
c2;
c3[fillcolor=red];
c4[fillcolor=green];
node[shape=none, fillcolor=transparent];
d1[label="Label 1"];
d2[label="Label 2"];
d3[label="Label 3"];
d4[label="Label 4"];
edge[dir=none];
a1->b1;
a2->b1;
b1->c1;
c1->d1[style=invis];
a3->b2[dir=forward, fillcolor=red, color=red];
a4->b2;
b2->c2;
c2->d2[style=invis];
a5->b3[dir=forward, fillcolor=red, color=red];
a6->b3[dir=forward, fillcolor=red, color=red];
b3->c3;
c3->d3[style=invis];
a7->b4[dir=forward, fillcolor=green, color=green];
a8->b4[dir=forward, fillcolor=green, color=green];
b4->c4;
c4->d4[style=invis];
edge[style=invis];
a2 -> a3;
a4 -> a5;
a6 -> a7;
}

How can I get the boxes in the same line?

I have read this link --> Forcing "main line" nodes into a straight line in Graphviz (or alternatives)
Despite using this - I can not get this right. What do I do wrong?
Why is not the node number 3 at the same level=height when I have put the weight at the same as no 2? Why is node 5 not at the same level=height as no 4 dispite using the same weight?
Is there any why to have the same left margin with the boxes 1 and 4
Thanks!
F
<graphviz>
digraph MMM8
{
rankdir=LR
node [shape=box, width="0.8", height="0.5", fontsize="10"];
edge [weight=2]
1, 2, 3, 6, 7;
edge [weight=1]
4, 5, Nod1, 8;
node [shape = box];
1 [label = "111111111111"];
2 [label = "2"];
3 [label = "3"];
4 [label = "4"];
5 [label = "5"];
6 [label = "6"];
7 [label = "7"];
8 [label = "7"];
9 [label = "9"];
Nod1 [label="N1", shape=diamond,style=filled,label="",height=.1,width=.1] ;
{
1-> 2[label="C1"]
2-> 3
3 -> Nod1
4->Nod1
Nod1->5
5->6
6-> 7
5->8
8-> 9
9-> 7
{
rank = same;
1, 4
}
{
rank = same;
6,8
}
}
</graphviz>
You've got to create a subgroup with rank=same and include each node you want inline in the subgroup.
digraph MMM8
{
rankdir=LR
node [shape=box, width="0.8", height="0.5", fontsize="10"];
node [shape = box];
{
rank=same;
1 [label = "111111111111"];
2 [label = "2"];
3 [label = "3"];
6 [label = "6"];
7 [label = "7"];
}
{
rank=same;
4 [label = "4"];
5 [label = "5"];
8 [label = "8"];
Nod1 [label="N1", shape=diamond,style=filled,label="",height=.1,width=.1] ;
}
9 [label = "9"];
1-> 2[label="C1"];
2-> 3;
3 -> Nod1;
4->Nod1;
Nod1->5;
5->6 ;
6-> 7;
5->8;
8-> 9;
9-> 7;
}
If you want to get all those nodes in line, then you'll have to combine the two subgroups into one and move node 9 into it.

Resources