I am trying to create a plot of a binary, coloring and marking different nodes in different colors.
To get the borders around the subtrees I use subgraphs which works almost perfectly fine:
graph G
{
graph [ranksep="0.25", nodesep="0.25"]
rankdir = TB;
node [shape=ellipse, style=filled, fillcolor="#0068B4", color=white, fontcolor=white, penwidth=10]
edge [arrowtail="none"]
subgraph cluster_0 {
node [fillcolor="#99CC00"]
color="#99CC00"
style=filled
fillcolor=white
fontcolor="#99CC00"
label="12 is the root of\n26's left child\r"
18;
subgraph cluster_01 {
node [fillcolor="#00B0F0"]
color="#00B0F0"
fontcolor="#00B0F0"
style=filled
fillcolor=white
label="4 is the root of \n12's left child \r"
7 [fillcolor=white]
4 -- 13
4 -- 7 [style=invisible]
7 -- 13 [style=invisible]
{ rank=same; 7, 13 }
{ rank=same; 4, 18 }
}
12 -- {4,18}
{ rank=same; 12 }
}
subgraph cluster_1 {
node [fillcolor="#C00000"]
color="#C00000"
style=filled
fillcolor=white
fontcolor="#C00000"
label="32 is the root of\n26's right child\r"
35 [fillcolor=white]
32 -- 38
32 -- 35 [style=invisible]
35 -- 38 [style=invisible]
{ rank=same; 32 }
{ rank=same; 35, 38 }
}
26 -- {12, 32}
{ rank=same; 26 }
}
which leads to this output:
As you can see, the node 18 is placed inside the blue subcluster. Is there an easy way to move that node "out of the box" other than placing a blank dummy node (like the invisible nodes 7 and 35) between 4 and 18?
But, adding graph [newrank=true] and rearranging a few lines makes things better:
graph G
{
graph [ranksep="0.25", nodesep="0.25" newrank=true]
rankdir = TB;
node [shape=ellipse, style=filled, fillcolor="#0068B4", color=white, fontcolor=white, penwidth=10]
edge [arrowtail="none"]
subgraph cluster_0 {
node [fillcolor="#99CC00"]
color="#99CC00"
style=filled
fillcolor=white
fontcolor="#99CC00"
label="12 is the root of\n26's left child\r"
subgraph cluster_01 {
node [fillcolor="#00B0F0"]
color="#00B0F0"
fontcolor="#00B0F0"
style=filled
fillcolor=white
label="4 is the root of \n12's left child \r"
7 [fillcolor=white]
4 -- 13
4 -- 7 [style=invisible]
7 -- 13 [style=invisible]
{ rank=same; 7, 13 }
}
{ rank=same; 4, 18 }
12 -- {4,18}
{ rank=same; 12 }
}
subgraph cluster_1 {
node [fillcolor="#C00000"]
color="#C00000"
style=filled
fillcolor=white
fontcolor="#C00000"
label="32 is the root of\n26's right child\r"
35 [fillcolor=white]
32 -- 38
32 -- 35 [style=invisible]
35 -- 38 [style=invisible]
{ rank=same; 32 }
{ rank=same; 35, 38 }
}
26 -- {12, 32}
{ rank=same; 26 }
}
Gives:
graph is built by Graphviz:
graph {
layout=circo;
subgraph cluster_0 {
1 -- { 2 3 4 5 6 }
2 -- { 3 4 5 6 }
3 -- { 4 5 6 }
4 -- { 5 6 }
5 -- { 6 }
};
subgraph cluster_1 {
a -- b;
a -- c;
a -- d;
1 -- a;
};
}
How to align cluster_1 to the bottom of cluster_0?
If I have a graphviz dot script like this:
digraph g {
node [style=rounded, shape=box]
subgraph cluster1 {
style="invis"
1 -> 2 -> 3 -> 4 -> 5
}
subgraph cluster2 {
style="invis"
6 -> 7
7 -> 8 -> 11
7 -> 9 -> 11
7 -> 10 -> 11
}
edge[constraint=false];
splines="ortho"
5 -> 6 [weight=0]
}
I get an output that looks like this (what I want):
However, if the labels in some of the nodes at the end become too long, the arrangement gets reversed like this:
digraph g {
node [style=rounded, shape=box]
8 [label="very long label"]
9 [label="very long label"]
10 [label="very long label"]
subgraph cluster1 {
style="invis"
1 -> 2 -> 3 -> 4 -> 5
}
subgraph cluster2 {
style="invis"
6 -> 7
7 -> 8 -> 11
7 -> 9 -> 11
7 -> 10 -> 11
}
edge[constraint=false];
splines="ortho"
5 -> 6 [weight=0]
}
How can I prevent this and force the original ordering method to occur?
You will have to define your long labels after having defined the other; graphviz draws the nodes in the order the are defined.
digraph g {
node [style=rounded, shape=box]
subgraph cluster1 {
style="invis"
1 -> 2 -> 3 -> 4 -> 5
}
subgraph cluster2 {
style="invis"
6 -> 7
7 -> 8 -> 11
7 -> 9 -> 11
7 -> 10 -> 11
}
8 [label="very long label"]
9 [label="very long label"]
10 [label="very long label"]
edge[constraint=false];
splines="ortho"
5 -> 6 [weight=0]
}
yields
Using the following command:
dot -Tpng so.dot -o so.png
the graphviz code shown produces the (650x255) image further down. I like that there are 3 distinct horizontal levels in the output image, but I'd prefer the difference in height between these 3 levels to be increased; perhaps producing a taller image. Can anyone help?
digraph G {
node [shape="circle"];
1 -> { 2; 3; 4 }
2 -> { 5; 6; 7 }
3 -> { 8; 9; 10 }
4 -> { 11; 12; 13 }
}
Try
dot -Tpng -Granksep=3.0 so.dot -o so.png
which gives
Documentation: http://soc.if.usp.br/manual/graphviz/html/info/attrs.html#a:ranksep
digraph {
1 -> 2 -> 3;
2 -> { rank = sink; end};
}
How can I force the "end" node to be centered horizontally (in the same column as the first node)?
You may use the group attribute of the nodes:
digraph {
3[group=b];
node[group=a]
1 -> 2 -> end;
2 -> 3;
}
See also this and this answer.