How to align subgraph to the bottom of another subgraph? - graphviz

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?

Related

Graphviz non-overlapping tree

I am trying to use Graphviz to produce a tree such as the following:
I have it almost working, as shown below:
My problems are the following:
Subtrees should never overlap, but the PP tree and the (.) tree overlap.
Subtrees should always be fairly regular, so that if there are multiple children, the edges should go to the left and right of the parent. Again, this does not work properly for the PP tree.
I have fixed (1) by using subgraph clusters, however, this introduces a few new issues. Namely, the edges are not straight, and I can't figure out how to hide the borders without leaving tons of empty space.
Is there a better way to force the tree formatting? It feels like it shouldn't be too unusual.
My code is below (generated by Python, sorry for unhelpful names):
graph {
subgraph 0 {
subgraph 1 {
0 [label=ROOT group=0 shape=plain]
subgraph 8 {
1 [label=S group=1 shape=plain]
subgraph 11 {
2 [label=NP group=2 shape=plain]
subgraph 15 {
3 [label=PRP group=3 shape=plain]
4 [label=I shape=plain]
3 -- 4
4 [label=I group=3]
}
2 -- 3
3 [label=PRP group=2]
}
subgraph 24 {
5 [label=VP group=5 shape=plain]
subgraph 28 {
6 [label=VBD group=6 shape=plain]
7 [label=solved shape=plain]
6 -- 7
7 [label=solved group=6]
}
subgraph 41 {
8 [label=NP group=8 shape=plain]
subgraph 45 {
9 [label=DT group=9 shape=plain]
10 [label=the shape=plain]
9 -- 10
10 [label=the group=9]
}
subgraph 63 {
11 [label=NN group=11 shape=plain]
12 [label=problem shape=plain]
11 -- 12
12 [label=problem group=11]
}
8 -- 9
8 -- 11
}
subgraph 77 {
13 [label=PP group=13 shape=plain]
subgraph 81 {
14 [label=IN group=14 shape=plain]
15 [label=on shape=plain]
14 -- 15
15 [label=on group=14]
}
subgraph 89 {
16 [label=NP group=16 shape=plain]
subgraph 93 {
17 [label=DT group=17 shape=plain]
18 [label=the shape=plain]
17 -- 18
18 [label=the group=17]
}
subgraph 102 {
19 [label=NN group=19 shape=plain]
20 [label=bus shape=plain]
19 -- 20
20 [label=bus group=19]
}
16 -- 17
16 -- 19
}
13 -- 14
13 -- 16
}
5 -- 6
5 -- 8
5 -- 13
}
subgraph 114 {
21 [label="." group=21 shape=plain]
22 [label="." shape=plain]
21 -- 22
22 [label="." group=21]
}
1 -- 2
1 -- 5
1 -- 21
}
0 -- 1
1 [label=S group=0]
}
}
ranksep=0.2
}
You are correct, Graphviz has "problems" with trees. That said, here is your graph, with clusters (peripheries=0), splines=false, and margin=2:
graph {
graph [splines=false]
subgraph cluster_0 {
peripheries=0
margin=2
subgraph cluster_1 {
0 [label=ROOT group=0 shape=plain]
subgraph cluster_8 {
1 [label=S group=1 shape=plain]
subgraph cluster_11 {
2 [label=NP group=2 shape=plain]
subgraph cluster_15 {
3 [label=PRP group=3 shape=plain]
4 [label=I shape=plain]
3 -- 4
4 [label=I group=3]
}
2 -- 3
3 [label=PRP group=2]
}
subgraph cluster_24 {
5 [label=VP group=5 shape=plain]
subgraph cluster_28 {
6 [label=VBD group=6 shape=plain]
7 [label=solved shape=plain]
6 -- 7
7 [label=solved group=6]
}
subgraph cluster_41 {
8 [label=NP group=8 shape=plain]
subgraph cluster_45 {
9 [label=DT group=9 shape=plain]
10 [label=the shape=plain]
9 -- 10
10 [label=the group=9]
}
subgraph cluster_63 {
11 [label=NN group=11 shape=plain]
12 [label=problem shape=plain]
11 -- 12
12 [label=problem group=11]
}
8 -- 9
8 -- 11
}
subgraph cluster_77 {
13 [label=PP group=13 shape=plain]
subgraph cluster_81 {
14 [label=IN group=14 shape=plain]
15 [label=on shape=plain]
14 -- 15
15 [label=on group=14]
}
subgraph cluster_89 {
16 [label=NP group=16 shape=plain]
subgraph cluster_93 {
17 [label=DT group=17 shape=plain]
18 [label=the shape=plain]
17 -- 18
18 [label=the group=17]
}
subgraph cluster_102 {
19 [label=NN group=19 shape=plain]
20 [label=bus shape=plain]
19 -- 20
20 [label=bus group=19]
}
16 -- 17
16 -- 19
}
13 -- 14
13 -- 16
}
5 -- 6
5 -- 8
5 -- 13
}
subgraph cluster_114 {
21 [label="." group=21 shape=plain]
22 [label="." shape=plain]
21 -- 22
22 [label="." group=21]
}
1 -- 2
1 -- 5
1 -- 21
}
0 -- 1
1 [label=S group=0]
}
}
ranksep=0.2
}
Giving:

Placement of nodes in a nested subgraph in Graphviz

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:

Graphviz - how to set different layouts for each subgraph?

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;
};
}
This command is executed to save output as PNG file
dot -Tpng example.dot -o example.png
The result:
I would like to set different layouts for each subgraphs. For example, circo for cluster_0 and twopi for cluster_1. How can I do it?

How to prevent the subgraph cluster alignment order from being reversed?

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

graphviz: minor tweaks to make the graph look nicer

I have a test graph here that I would like to tweak to make it look nicer.
Here is the graphviz (dot) source, test6.dot:
digraph G {
ranksep=0.3; size="6.0,6.0";
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
node [style=filled];
1 -> 2 -> 3 -> X2 -> 5;
6;
7;
label = "A";
color=blue
}
X1 [shape=box];
subgraph clusterB {
node [style=filled];
8;
9;
10 -> 11 -> 12;
12 -> 9;
12 -> 8 -> 13;
13 -> 14;
label = "B";
color=blue
}
subgraph clusterC {
label = "C";
{
node [style="invis"];
gap;
}
node [shape=box];
edge [style="invis"];
X3 -> gap -> X4;
}
14 -> X4 -> 3;
6 -> X1 -> 10;
{ edge [dir="both"];
8 -> X3 -> 7;
}
9 -> X3
}
Questions / changes I would like to make:
I want the flow of nodes 10 -> 11 -> 12 -> 8 -> 13 -> 14 to be in a vertical line (swap 8 and 9 horizontally). How can I do this? (same with 1 -> 2 -> 3 -> X2 -> 5; swap 6 and 1)
I want X1 to be at the same vertical position as 10, and the same horizontal position as 6. How can I do this?
I want 8 and X3 and 7 to be at the same vertical position, also with 14 and X4 and 3. How can I do this?
The ranksep=0.3; statement works great except note that 8 -> 13 -> 14 has a larger gap, as does X3 -> gap -> X4. Why doesn't it obey the ranksep=0.3 rule, and how do I fix this?
Below is the best I can do: phantom nodes and edges help. But I can't seem to encourage a particular ordering in the transverse direction (the other direction from rankdir).
digraph G {
ranksep=0.3; size="6.0,6.0";
rankdir=TB;
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
label = "A";
color=blue;
node [style=filled];
/* force 1, 6, and 7 to be at the top together,
add enough phantoms to keep things in nice columns */
{
node [style="invis", label=""];
phantom3;
phantom4;
phantom5;
phantom6;
}
rank = same;
1 -> 2 -> 3 -> X2 -> 5;
edge [style="invis"];
6 -> phantom3 -> phantom5;
7 -> phantom4 -> phantom6;
}
subgraph clusterB {
node [style=filled];
label = "B";
color=blue;
/* create an invisible phantom node
to take up space */
{
node [style="invis",label=""];
phantom1;
phantom1b;
}
{ rank=same; 11;
phantom1;
}
10 -> 11 -> 12 -> 8 -> 13 -> 14;
12 -> 9;
phantom1 -> 9 -> phantom1b [style="invis"];
}
/* force X1 to be at the same vertical pos as 10
(this yields a warning though) */
{ rank = same;
X1 [shape=box];
10;
}
6 -> X1;
X1 -> 10 [weight=0.5];
subgraph clusterC {
label = "C";
phantom2 [style="invis", label=""];
node [shape=box];
edge [style="invis"];
X3 -> phantom2 -> X4;
}
9 -> X3 [weight=0.5];
{
edge [weight=20];
14 -> X4 -> 3;
3 -> X4 -> 14 [style="invis"];
/* add a reverse path so graphviz doesn't force 14 above X4 above 3 */
}
{
edge [dir="both", weight=20];
8 -> X3 -> 7;
7 -> X3 -> 8 [style="invis"];
edge [style="invis"];
X4 -> phantom6;
1 -> phantom2;
8 -> phantom2;
}
}

Resources