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

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:

Related

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 make an edge with both direction in GraphViz?

How to make an edge with both direction in GraphViz?
I am trying to make an curved edge with both direction.
But the only plot I can make is:
I want to make the edge between x1 and x2 curved with both direction.
The code I used:
digraph {
rankdir=LR
node [shape=box ]
x1;x2
node [shape=oval ]
y
x1->y[dir=back label=0.77]
x2->y[dir=back label=0.42]
x1:w -> x2:w[dir=both constraint=false]
}
I would appreciate any help.
I think there should be a better solution but the following did work for me:
digraph {
rankdir=LR
node [shape=box ]
x1;x2
node [shape=oval ]
y
x1->y[dir=back label=0.77]
x2->y[dir=back label=0.42]
x1:w -> x2:w[dir=both constraint=false]
x2:w -> x1:w[dir=both constraint=false]
}
based on the answer from Changing edge direction in dot:
digraph g {
rankdir=LR
node [shape=box ]
{rank=same x1;x2}
node [shape=oval ]
y
x1 -> y[dir=back label=0.77]
x2 -> y[dir=back label=0.42]
x1:w -> x2:w[dir=both label=0.34]
}

GraphViz - alignment of subgraph

I'd like to draw a diagram like this.
But the only diagram I can draw is:
The code I used :
graph [rankdir = LR]
node [shape=box]
x1;x2;x3;y1;y2;y3;y4;y5;y6;y7;y8;
node [shape=oval]
ind60;dem60;dem65
{x1,x2,x3} -> ind60[arrowhead=none arrowtail=normal dir=both]
{y1,y2,y3,y4} -> dem60[arrowhead=none arrowtail=normal dir=both]
dem65 -> {y5,y6,y7,y8}
ind60->dem60 dem60->dem65 ind60->dem65
How can I draw the desired plot?
A first step in what you want to achieve, using rank=same, invisible edges, groups, and constraint=false:
digraph {
node [shape=box]
{
rank=same;
y1;y2;y3;y4;
}
dem60[shape=oval];
{y1;y2;y3;y4} -> dem60 [dir=back];
{
rank=same;
x2 [group=left];
ind60[shape=oval];
dem65[shape=oval];
y6 [group=right];
x2 -> ind60 [dir=back];
ind60 -> dem65
dem65 -> y6;
}
// Invisible edges to order vertically node groups
edge[style=invis];
x1[group=left];
x3[group=left];
x1 -> x2 -> x3;
node[group=right];
y5 -> y6 -> y7 -> y8;
node[group=""]
edge[style=solid]
ind60->dem60
dem60->dem65
edge[constraint=false];
ind60 -> x1;
ind60 -> x3;
dem65 -> y5;
dem65 -> y7;
dem65 -> y8;
}
group enforces vertical alignement of nodes (of the same group).
rank=same makes nodes stay on the same rank.
Invisible edges enforce rank order within a vertical group.
constraint=false removes constraint calculation for some edges.
dir=back reverses displayed edge direction.

Reducing edge weight to zero in 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]

Draw two subgraph without connection, one under the other, in DOT?

For example:
digraph G {
rankdir = TB;
subgraph A {
a -> {a0, a1};
};
subgraph B {
b -> {b0, b1, b2};
};
};
I want to put B at the bottom of A, how to do it?
You'll have to tell graphviz that the subgraphs are not equal. One way to do it is simply to add invisible edges between the graphs:
digraph G {
rankdir = TB;
subgraph A {
a -> {a0, a1};
};
subgraph B {
b -> {b0, b1, b2};
};
a0 -> b [style=invis];
a1 -> b [style=invis];
};
By adding two invisible edges the subgraphs are neatly aligned.

Resources