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

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.

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 do I vertically align a node with the center of a cluster?

I am looking for a way to align individual nodes in graphviz with an entire subgraph/cluster.
I am currently teaching a small team of analysts to use rmarkdown and I want to allow them to include simple graphs and flowcharts in their documents. I therefore use DiagrammeR (and viz.js) to render charts written in dot. To increase user adoption, I want to minimize complexity and avoid HTML and use raw dot.
Our problem is that we frequently try to align nodes with subgraphs/clusters containing multiple nodes, but we cannot align the entire subgraph with the node. Alignment only works with the constituent nodes within the subgraph/cluster. (see nodes C,D,E and G,T below)
I have tried to create a record node using GT [shape = record label="{G | T}"] but that does not allow individual styling of the two nodes.
I have also tried creating an HTML record node which allows individual styling but increases complexity too much and requires users to know HTML.
Finally, I have tried to insert an invisible node inside the clusters to "simulate" the center and then use the invisible node for alignment. This unfortunately pushes G and T to far apart and doesn't achieve the intended effect.
digraph G {
graph [splines = false, ranksep = 0.2]
edge [style = "invis"]
node [shape = box, width = 7.5]
A B H
node [shape = circle, width = 1.5]
subgraph cluster_2 {
rank = same
C D E
}
subgraph cluster_1 {
G [shape = box]
T [shape = box]
}
A -> B
G -> T
B -> {C D E G}
{C D E T} -> H
}
The following gives the output:
In the picture above, the subgraph containing G and T is not aligned with the subgraph containing C,D,E.
Is there a way to vertically align the centers of the two subgraphs?
The problem is that GraphViz only align node rows and {C D E} is one row where as {G->T} is two rows so {C D E} can only be align with either G or T
You can however align {C D E} with the space between G and T though that is probably not what you want. E.g. like this:
digraph G {
graph [splines = false, ranksep = 0.2]
//edge [style = "invis"]
node [shape = box, width = 7.5]
A B H
node [shape = circle, width = 1.5]
subgraph cluster_2 {
rank = same
C D E
}
subgraph cluster_1 {
G [shape = box]
T [shape = box]
}
A -> B
G -> T[minlen=2]
B -> G
B -> {C D E} -> H [minlen=2]
T -> H
}
Resulting in:

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.

Forcing edges on one side of a graph in DOT

In the following graph in DOT
graph {
rankdir=LR;
ranksep="1.0";
"v_1086" [label="A"];
"v_1023" [label="B"];
"v_1181" [label="C"];
"q_-888017763" [label="Q"];
"c_-961691100" [label="1"];
"c_-1161934348" [label="2"];
"c_556655049" [label="3"];
"v_1023"--"c_-961691100"[label="1.0"];
"v_1086"--"c_-1161934348"[label="1.0"];
"v_1181"--"c_556655049"[label="0.9925742574257426"];
"q_-888017763"--"v_1086" [color="green"];
"q_-888017763"--"v_1181" [color="indigo"];
"q_-888017763"--"v_1023" [color="khaki4"];
"c_-1161934348"--"c_-961691100"[label="1.0"];
"c_556655049"--"c_-1161934348"[label="0.10282888897110791"];
"c_556655049"--"c_-961691100"[label="0.006661529339994344"];
{rank = same;
"v_1086";
"v_1023";
"v_1181";
};
{rank = same;
"q_-888017763";
};
{rank = same;
};
{rank = same;
"c_-961691100";
"c_-1161934348";
"c_556655049";
};
}
How can I move the edges between the numerical nodes to the left.
The dot in the question renders as:
In that context, I don't understand the question: The numerical nodes are on the right, not the left, and I don't understand why you'd want to move the edges between them. Move them where?
Sorry this isn't an answer, but I can't embed an image in a comment.

Resources