Reducing edge weight to zero in graphviz - graphviz

I have created a graph using graphviz that I'm pretty happy with and I need to add one more edge to it. I currently have this:
(source for this in dot below)
I need to add an edge from T to S (in green!) but when I do so all the rest of the graph is thrown in to disarray. I know that I'm meant to just let graphviz take care of the layout but this graph forms one of a sequence and I'd like them to at least mostly look alike. I've tried various things with graph clusters and using weights to make all the other edges very high weight and the new edge very low but nothing seems to help. How can I add an edge from T to S which doesn't worry about the fact that that edge will have to be quite long.
The dot source for what I have is
digraph G {
rankdir=LR
subgraph clusterD3 {
vSource [label="S*"]
subgraph clusterD2 {
color=white
S
T
subgraph clusterD1 {
color=white
{rank=same; B A}
{rank=same; D C}
A->C
B->D
A->D
C->D
B->A
}
S->A
S->B
C->T
D->T
}
vSink [label="T*"]
vSource->A [color=red]
vSource->B [color=red]
vSource->C [color=red]
vSource->D [color=red]
vSource->T [color=red]
A->vSink [color=blue]
B->vSink [color=blue]
C->vSink [color=blue]
D->vSink [color=blue]
S->vSink [color=blue]
}
}

Adding
{rank=same;vSource;S}
solves the issue:
digraph G {
rankdir=LR
subgraph clusterD3 {
vSource [label="S*"]
subgraph clusterD2 {
color=white
S
T
{rank=same;vSource;S}
subgraph clusterD1 {
color=white
{rank=same; B A}
{rank=same; D C}
A->C
B->D
A->D
C->D
B->A
}
S->A
S->B
C->T
D->T
}
vSink [label="T*"]
vSource->A [color=red]
vSource->B [color=red]
vSource->C [color=red]
vSource->D [color=red]
vSource->T [color=red]
A->vSink [color=blue]
B->vSink [color=blue]
C->vSink [color=blue]
D->vSink [color=blue]
S->vSink [color=blue]
T -> S [color=green]
}
}

constraint=false also works:
T -> S [color=green,constraint=false]

Related

Graphviz: the vertical edge is impact by [style=invis], how to make the edges vertical

I have some digraph, which I have to use the [style=invis] to define the node order; but I found the original vertical edge is impacted by [style=invis], below is the digraph:
digraph G {
edge [dir=none];
R_35->p92;
R_35->p93;
c_p92 [shape=diamond];
{rank=same; p92 -> c_p92};
R_38 [shape=box];
c_p92->R_38;
R_38->p21;
c_p93 [shape=diamond];
{rank=same; p93 -> c_p93};
R_36_0 [shape=box];
R_36_0->p96;
R_36_1 [shape=box];
R_36_1->p97;
R_36_0->R_36_1
c_p93->R_36_1;
c_p92->p93[style=invis];
R_38->R_36_0[style=invis];
p21->p96->p97[style=invis];
{rank=same; p92; c_p92; p93;c_p93;};
{rank=same; R_38; R_36_0; R_36_1};
{rank=same; p21; p96; p97;};
}
I hope the edges from node "c_p92" to "R_38", from node "R_36_1" to "p97" are vertical, but they are impacted by the [style=invis] that, it seems they are attracted by each other and the edge is tilt. Can any one help me to figure out how to make these edges vertical?
You could assign the same group to all nodes of a 'string' of nodes should be aligned vertically - for example group=a for nodesc_p29, R38, p21 and group=b for nodes c_p93, R_36_1, p97:
digraph G {
edge [dir=none];
R_35->p92;
R_35->p93;
c_p92 [shape=diamond, group=a];
{rank=same; p92 -> c_p92};
R_38 [shape=box, group=a];
c_p92->R_38;
p21[group=a];
R_38->p21;
c_p93 [shape=diamond, group=b];
{rank=same; p93 -> c_p93};
R_36_0 [shape=box];
R_36_0->p96;
R_36_1 [shape=box, group=b];
p97[group=b];
R_36_1->p97;
R_36_0->R_36_1
c_p93->R_36_1;
c_p92->p93[style=dotted];
R_38->R_36_0[style=dotted];
p21->p96->p97[style=dotted];
{rank=same; p92; c_p92; p93;c_p93;};
{rank=same; R_38; R_36_0; R_36_1};
{rank=same; p21; p96; p97;};
}
Graphivz tries to align nodes of the same group.
(changed invis edges to dotted to see what's what)
A good way to get vertical edges (assuming rankdir=TB) is to use the group attribute (https://graphviz.org/docs/attrs/group/ and https://forum.graphviz.org/t/a-question-about-the-group-attribute-what-does-straight-mean/548/2). Like so:
digraph G {
edge [dir=none];
R_35->p92;
R_35->p93;
c_p92 [shape=diamond group=V1];
{rank=same; p92 -> c_p92};
R_38 [shape=box group=V1];
c_p92->R_38 [color=red];
R_38->p21;
c_p93 [shape=diamond];
{rank=same; p93 -> c_p93};
R_36_0 [shape=box];
R_36_0->p96;
R_36_1 [shape=box group=YY];
R_36_1->p97 [color=red];
R_36_0->R_36_1
c_p93->R_36_1;
c_p92->p93[style=invis];
R_38->R_36_0[style=invis];
p21->p96->p97[style=invis];
{rank=same; p92; c_p92; p93;c_p93};
{rank=same; R_38; R_36_0; R_36_1};
{rank=same; p21; p96; p97 [group=YY]}
}
Giving:

Controlling the ordering of nodes within a GraphViz subgraph cluster

I've got two cluster subgraphs in GraphViz, with edges between the nodes in each subgraph. I'd like to be able to influence the top-to-bottom ordering of the nodes within the second subgraph so as to achieve symmetry across the horizontal axis, and have the nodes in the second subgraph ordered top-to-bottom as a, b, c, d.
digraph {
rankdir=LR
subgraph cluster_1 {
bx -> cx
by -> cy
}
subgraph cluster_2 {
a; b; c; d
}
bx -> a
cx -> b
cy -> c
by -> d
}
Right now, I get this:
Changing the ordering of node appearance within the cluster_2 subgraph doesn't seem to matter, nor does changing the ordering of the cross-cluster edges at the bottom.
Is there any way to get GraphViz to produce what I want here?
You can add some scaffolding edges and/or nodes i.e. invisible edges/nodes but it can be a bit triggy especially when clusters are involved
e.g.:
digraph {
rankdir=LR
subgraph cluster_1 {
bx -> cx
by -> _d [dir=none]
by -> cy
_a[shape=point height=0]
_d[shape=point height=0]
bx -> _a [dir=none]
}
subgraph cluster_2 {
a; b; c; d
}
//bx -> a
cx -> b
cy -> c
//by -> d
_a->a
_d->d
}

How to have multiple label one above and one below the edges in graphviz?

I've the following output currently I want to place a label below the edge between p and z in the figure.Is it possible to do in graphviz I've tried using xlabels but it doesn't work.
Current Code:
digraph GPG{
node [shape=box];
subgraph cluster0{
node[shape=circle];
0[label=0,style=invis];
}
subgraph cluster1{
node[shape=circle];
1[label=1,style=invis];
p->z [label="2 | 1",minlen=1];
{
rank = same;
p;z;
}
}
subgraph cluster2{
node[shape=circle];
2[label=2,style=invis];
}
0->1
1->2
}
I want a label below edge p->z as well above the edge.Is it possible in graphviz?
Kind of ugly, but:
digraph overunder{
splines=false
{ rank=same
a -> b [label=" over " ]
a -> b [label="under" penwidth=0.0 dir=none]
}
}
Produces:
You may have to add the non-breaking space characters (see above) because Graphviz seems to position labels based on the length of the text - longer labels are placed above shorter labels.

How to structure multiple subgraphs in Graphviz?

My ultimate aim is to write a python script that will automatically generate graphviz graphs based on some input data. However, I'm first focusing just on the graphviz.
This is currently what I have:
digraph G {
compound=true;
node [shape=box];
edge [dir=none];
subgraph cluster_overall{
subgraph cluster_top{
apple;
banana;
}
subgraph clustermsc{
basket1;
basket2;
label="Baskets";
}
subgraph cluster_bottom{
orange;
kiwi;
}
label="Test";
}
apple -> basket1;
banana -> basket2;
orange -> basket1;
kiwi -> basket2;
}
Current: https://i.imgur.com/76GCx0f.png
This is what I want my final graph to look like. With the number of fruits evenly distributed between the top and bottom section (based on the input date):
Final: https://i.imgur.com/OHFsAdd.png
How do I structure the page to have 3 static, separate sections. Currently the fruit's placement constantly changes based on node they point to.
Please let me know if I wasn't clear in my explanation, I'll try better explaining it. Thanks.
Don't have enough repuation to directly post images.
In graphviz, it is important to produce the hierarchy as the tool sees it, not reproducing the logic that is on your mind. simply reversing the edges from your baskets to the "lower" fruits does the job:
digraph G {
compound=true;
node [shape=box];
edge [dir=none];
subgraph cluster_overall{
subgraph cluster_top{
apple;
banana;
}
subgraph clustermsc{
basket1;
basket2;
label="Baskets";
}
subgraph cluster_bottom{
orange;
kiwi;
}
label="Test";
}
apple -> basket1;
banana -> basket2;
basket1 -> orange; // !!!
basket2-> kiwi; // !!!
}
gives you
If you want to force a certain order of items (such as apple being to the left of banana), you can do so by replacing your definition with
subgraph cluster_top{
{ rank = same; apple -> banana[ style = invis ] }
}
If I correctly understood you, you need to connect clusters with invisible edges to force their position.
Here I've added a dummy node into each cluster (because to connect clusters you have to connect nodes in these clusters and then add lhead and ltail attributes).
Then I've connected these clusters in the correct order with invisible edges. Also I've added an extremely big weight to these edges to give them priority over other edges.
Is that what you need?
digraph G {
compound=true;
node [shape=box];
edge [dir=none];
subgraph cluster_overall{
subgraph cluster_top{
dummy_top [shape=point width=0 style=invis]
apple;
banana;
}
subgraph clustermsc{
dummy_msc [shape=point width=0 style=invis]
basket1;
basket2;
label="Baskets";
}
subgraph cluster_bottom{
dummy_bottom [shape=point width=0 style=invis]
orange;
kiwi;
}
label="Test";
}
dummy_top -> dummy_msc [
style=invis
weight=100
lhead="clustermsc"
ltail="cluster_top"
]
dummy_msc -> dummy_bottom [
style=invis
weight=100
lhead="cluster_bottom"
ltail="clustermsc"
]
apple -> basket1;
banana -> basket2;
orange -> basket1;
kiwi -> basket2;
}

Graphviz: Intersecting but non-recursive clusters

I was wondering if it's possible to do something like this in Graphviz:
As you can see, node "two" is inside two clusters while the clusters aren't recursive.
Note: Image made with Dia.
No, this is currently not possible
Just rewriting Jens' comment as an answer.
While Graphviz won't produce overlapping clusters directly, it will allow you to create overlapping clusters with a bit of editing. (For more info see: https://www.graphviz.org/faq/#FaqDotWithCoords)
Start with:
digraph o {
graph [newrank=true nodesep=.5]
subgraph cluster1 {
graph [margin=50 label="Subgraph 1"]
{rank=same
one-> two [style=invis]
}
}
subgraph cluster2 {
graph [label="Subgraph 2"]
three
}
{rank=same
one two three
}
}
run this command: dot -Tdot myfile.gv >myfile.dot
Then edit myfile.dot to change the boundary box of cluster2. Like so:
digraph o {
graph [bb="0,0,398,175",
newrank=true,
nodesep=.5
];
node [label="\N"];
{
graph [rank=same];
one [height=0.5,
pos="85,76",
width=0.75827];
two [height=0.5,
pos="176,76",
width=0.77632];
three [height=0.5,
pos="340,76",
width=0.99297];
}
subgraph cluster1 {
graph [bb="8,8,254,167",
label="Subgraph 1",
lheight=0.21,
lp="131,155.5",
lwidth=1.17,
margin=50
];
{
graph [rank=same];
one;
two;
one -> two [pos="e,147.67,76 112.37,76 120.74,76 129.1,76 137.46,76",
style=invis];
}
}
subgraph cluster2 {
graph [bb="135,50,390,125", // X1 edited
label="Subgraph 2",
lheight=0.21,
lp="340,113.5",
lwidth=1.17
];
three;
}
}
run this command on the edited file: neato -n2 -Tpng myfile.dot >myfile.png
Giving:

Resources