strictly left to right orthogonal arcs in graphviz - graphviz

This question is a continuation of this question.
In addition to strictly east-to-west arcs, I would also like them to be orthogonal (ie not curved.) So I added the attribute "splines=ortho" to the dot file, like this:
digraph net {
graph [splines=ortho]
"C0" [shape=oval label="C0"]
"C1" [shape=oval label="C1"]
"B0" [shape=box label="B0"]
rankdir="LR"
"C0":e -> "B0":w
"B0":e -> "C1":w
"C1":e -> "B0":w
}
Now I am getting this image, where the arcs are going through the nodes:
Is it possible to get a picture like this, where the orthogonal arc moves around the nodes, something like this?

It is possible, but you have to DIY. Here we add lots of invisible nodes and then "connect the dots" (puns!).
Note the use of dir (https://graphviz.org/docs/attrs/dir/), headclip (http://www.graphviz.org/docs/attrs/headclip/), and tailclip (https://graphviz.org/docs/attrs/tailclip/) attributes.
digraph net {
graph [splines=false]
// rankdir="LR" << turned it off, makes things easier?
graph [nodesep=.07]
{
node [style=invis label=""]
I1 I2 I3 I4 I5 I6 X2 X4 X6
}
{rank=same I1 I2 I3 I4 I5 I6}
{rank=same C0 B0 C1 X2 X4 X6}
"C0" [shape=oval label="C0"]
"C1" [shape=oval label="C1"]
"B0" [shape=box label="B0"]
C0 -> X2 [dir=none headclip=false]
X2 -> B0 [tailclip=false]
B0 -> X4 [dir=none headclip=false]
X4 -> C1 [tailclip=false]
C1 -> X6 [dir=none headclip=false]
{
edge [dir=none tailclip=false headclip=false]
I6 -> X6
I2 ->I3 ->I4 -> I5 ->I6
}
I2 -> X2 [tailclip=false headclip=false]
}
Giving:

Related

Preserve order of nodes in grahpviz subgraph

How can I make the graphviz preserve the order of nodes in subgraph?
See the image and the code below. For some reason the second node (with the number 2) is displayed at the top and the first node is at the bottom.
I took a look at this questions but it did not solve the issue (or then I did not understand how to implement the suggestions properly):
Preventing graphviz from rearranging nodes
digraph G {
rankdir=LR
splines=line
nodesep=0.3;
ranksep=2
node [label=""];
// edge [dir=none];
edge[arrowhead="empty"];
// graph [ordering="out"];
subgraph cluster_0 {
color=white;
// {rank=same;x1;x2;x3;x4;x5}
node [style=solid,color=blue4, shape=circle];
x1 [label="1"] x2 [label="2"] x3 [label="3"] x4 [label="4"] x5 [label="5"];
}
subgraph cluster_1 {
color=white;
node [style=solid,color=red2, shape=circle];
edge[style=invisible]
a12 [label="1"] a22 [label="2"] a32 [label="3"] a42 [label="4"];
}
subgraph cluster_2 {
color=white;
node [style=solid,color=red2, shape=circle];
a13 a23 a33 a43;
}
subgraph cluster_3 {
color=white;
node [style=solid,color=seagreen2, shape=circle];
O1 O2 O3;
}
x1 -> a12;
x1 -> a22;
x1 -> a32;
x1 -> a42;
x2 -> a12;
x2 -> a22;
x2 -> a32;
x2 -> a42;
x3 -> a12;
x3 -> a22;
x3 -> a32;
x3 -> a42;
x4 -> a12;
x4 -> a22;
x4 -> a32;
x4 -> a42;
x5 -> a12;
x5 -> a22;
x5 -> a32;
x5 -> a42;
a12 -> a13
a22 -> a13
a32 -> a13
a42 -> a13
a12 -> a23
a22 -> a23
a32 -> a23
a42 -> a23
a12 -> a33
a22 -> a33
a32 -> a33
a42 -> a33
a12 -> a43
a22 -> a43
a32 -> a43
a42 -> a43
a13 -> O1
a23 -> O1
a33 -> O1
a43 -> O1
a13 -> O2
a23 -> O2
a33 -> O2
a43 -> O2
a13 -> O3
a23 -> O3
a33 -> O3
a43 -> O3
}
I could not find a way to use ordering successfully, either. Because they did not seem to be used, I removed the cluster references. This version uses weight attributes to keep the nodes in order.
digraph G {
rankdir=LR
splines=line
nodesep=0.3;
ranksep=2
node [label=""];
edge[arrowhead="empty"];
{
rank=same
node [style=solid,color=blue4, shape=circle];
x1 [label="1"] x2 [label="2"] x3 [label="3"] x4 [label="4"] x5 [label="5"];
edge [weight=50] // arbitrarily large integer
edge [style=invis]
x1->x2 x2->x3 x3->x4 x4->x5
}
{
rank=same
node [style=solid,color=red2, shape=circle];
edge[style=invisible]
a12 [label="1"] a22 [label="2"] a32 [label="3"] a42 [label="4"];
edge [weight=50] // arbitrarily large integer
edge [style=invis]
a12->a22 a22->a32 a32->a42
}
{
rank=same
node [style=solid,color=red2, shape=circle];
a13 a23 a33 a43;
}
{
rank=same
node [style=solid,color=seagreen2, shape=circle];
O1 O2 O3;
}
x1 -> a12;
x1 -> a22;
x1 -> a32;
x1 -> a42;
x2 -> a12;
x2 -> a22;
x2 -> a32;
x2 -> a42;
x3 -> a12;
x3 -> a22;
x3 -> a32;
x3 -> a42;
x4 -> a12;
x4 -> a22;
x4 -> a32;
x4 -> a42;
x5 -> a12;
x5 -> a22;
x5 -> a32;
x5 -> a42;
a12 -> a13
a22 -> a13
a32 -> a13
a42 -> a13
a12 -> a23
a22 -> a23
a32 -> a23
a42 -> a23
a12 -> a33
a22 -> a33
a32 -> a33
a42 -> a33
a12 -> a43
a22 -> a43
a32 -> a43
a42 -> a43
a13 -> O1
a23 -> O1
a33 -> O1
a43 -> O1
a13 -> O2
a23 -> O2
a33 -> O2
a43 -> O2
a13 -> O3
a23 -> O3
a33 -> O3
a43 -> O3
}
Giving:
(yes, there many failures in between)

graphviz dot: how to change the orientation of a self pointing arrow?

I'm working on DOT with graphivz, I currently have this code:
digraph {
q0 -> q0[label="a"];
q0 -> q1[label="b"];
q1 -> q2[label="a"];
q1 -> q1[label="b"];
q2 -> q2[label="a"];
q2 -> q0[label="b"];
{ rank=same; q0, q1 }
q0[shape=circle];
q1[shape=circle];
q2[shape=circle, peripheries=2];
}
When rendering the graph I get:
:
Would it be possible to change the q0 -> q0 arrow so that it appears on top of the node or to its left so that it doesn't overlap with the q0 -> q1 edge?

Drawing ellipsis between nodes in graphviz

I'm interested in drawing vertical ellipsis between nodes in graphviz like seen below:
The problem I'm having is whenever I try to do this I cannot seem to get x3 and xn to line up vertically as seen here:
Here is what I have tried:
digraph G {
rankdir=LR
splines=line
subgraph cluster_0 {
color=white;
node [style=solid, color=black, shape=circle];
x1 x2 x3 xn [group=g1];
label = "Input Features";
}
subgraph cluster_1 {
color=white;
node [style=solid, color=red2, shape=circle];
a1 [group=g2];
label = "Activation";
}
subgraph cluster_2 {
color=white;
node [style=solid, color=green, shape=circle];
out [group=g3];
label = "Output";
}
x1 -> a1;
x2 -> a1;
x3 -> a1;
a1 -> out;
x3 -> xn [arrowhead="none", color="black:invis:black"];
}
I'm very new to graphviz so I'm not even sure if I'm using subgraph properly here. I also tried adding the nodes in the subgraphs to groups, but that didn't seem to do anything.
Add
{ rank = same; x1 x2 x3 xn }
x1 -> x2 -> x3[ style = invis ];
to your first subgraph. This has the effect that
the four nodes are all one one level, i.e. lining up vertically
the three numbered nodes stay together
Here my version:
digraph G
{
rankdir = LR
splines = line
subgraph cluster_0
{
color = white;
node[ style = solid, color = black, shape = circle];
{ rank = same; x1 x2 x3 xn }
x1 -> x2 -> x3[ style = invis ];
label = "Input Features";
}
subgraph cluster_1
{
color = white;
node[ style = solid, color = red2, shape = circle ];
a1;
label = "Activation";
}
subgraph cluster_2
{
color =white;
node[ style = solid, color = green, shape = circle ];
out;
label = "Output";
}
x1 -> a1;
x2 -> a1;
x3 -> a1;
a1 -> out;
x3 -> xn[ arrowhead = "none", color = "black:invis:black" ];
}
which gives you
E D I T to answer the question in your comment; the key is reversing the order of node definitions and edge direction within the same rank, probably caused by the rankdir = LR layout. After all, there is a simple solution!
digraph G
{
rankdir = LR
splines = line
subgraph cluster_0
{
color = white;
label = "Input Features";
node[ style = solid, color = black, shape = circle ];
/* define and connect in reverse order */
{ rank = same; xn x3 x2 x1 }
x3 -> x2 -> x1[ style = invis ];
xn -> x3[ arrowhead = "none", color = "black:invis:black" ];
}
subgraph cluster_1
{
color = white;
node[ style = solid, color = red2, shape = circle ];
a1;
label = "Activation";
}
subgraph cluster_2
{
color =white;
node[ style = solid, color = green, shape = circle ];
out;
label = "Output";
}
{ x1 x2 x3 } -> a1;
a1 -> out;
}

How to make node relative order fixed in graphviz?

I'm trying to draw a neural network in graphviz. Here is what my picture currently looks like:
As you can see, the order of the labels of the nodes don't appear correctly. For instance, I want $a_0^(2)$ sticks to the top of layer 2 and I want to arrange the rest of nodes in the same layer with numerical increasing order (i.e $a_1^(2)$, $a_2^(2)$, ...)
How can I do this? Much thanks!
Here is my code:
digraph G {
rankdir=LR;
splines=line;
nodesep=".05";
edge [comment="Wildcard node added automatic in EG."];
node [label=""];
subgraph cluster_0 {
color=white;
label="layer 1 (input layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=chartreuse,
style=filled,
shape=circle];
x0 [color=yellow,
fillcolor=yellow,
label=<x<sub>0</sub>>];
x1 [fillcolor=chartreuse,
label=<x<sub>1</sub>>];
x2 [fillcolor=chartreuse,
label=<x<sub>2</sub>>];
x3 [fillcolor=chartreuse,
label=<x<sub>3</sub>>];
}
subgraph cluster_1 {
color=white;
label="layer 2 (hidden layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=dodgerblue,
style=filled,
shape=circle];
a02 [color=yellow,
label=<a<sub>0</sub><sup>(2)</sup>>,
pos="0,0",
fillcolor=yellow];
a12 [label=<a<sub>1</sub><sup>(2)</sup>>,
pos="0,-1",
fillcolor=dodgerblue];
a22 [label=<a<sub>2</sub><sup>(2)</sup>>,
pos="0,-2",
fillcolor=dodgerblue];
a32 [label=<a<sub>3</sub><sup>(2)</sup>>,
pos="0,-3",
fillcolor=dodgerblue];
a42 [label=<a<sub>4</sub><sup>(2)</sup>>,
pos="0,-4",
fillcolor=dodgerblue];
a52 [label=<a<sub>5</sub><sup>(2)</sup>>,
pos="0,-5",
fillcolor=dodgerblue];
}
subgraph cluster_2 {
color=white;
label="layer 3 (hidden layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=dodgerblue,
style=filled,
shape=circle];
a03 [color=yellow,
fillcolor=yellow,
label=<a<sub>0</sub><sup>(3)</sup>>];
a13 [fillcolor=dodgerblue,
label=<a<sub>1</sub><sup>(3)</sup>>];
a23 [fillcolor=dodgerblue,
label=<a<sub>2</sub><sup>(3)</sup>>];
a33 [fillcolor=dodgerblue,
label=<a<sub>3</sub><sup>(3)</sup>>];
a43 [fillcolor=dodgerblue,
label=<a<sub>4</sub><sup>(3)</sup>>];
a53 [fillcolor=dodgerblue,
label=<a<sub>5</sub><sup>(3)</sup>>];
}
subgraph cluster_3 {
color=white;
label="layer 4 (output layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=coral1,
style=filled,
shape=circle];
O1 [fillcolor=coral1,
label=<a<sub>1</sub><sup>(4)</sup>>];
O2 [fillcolor=coral1,
label=<a<sub>2</sub><sup>(4)</sup>>];
O3 [fillcolor=coral1,
label=<a<sub>3</sub><sup>(4)</sup>>];
O4 [fillcolor=coral1,
label=<a<sub>4</sub><sup>(4)</sup>>];
}
x0 -> a12;
x0 -> a22;
x0 -> a32;
x0 -> a42;
x0 -> a52;
x1 -> a12;
x1 -> a22;
x1 -> a32;
x1 -> a42;
x1 -> a52;
x2 -> a12;
x2 -> a22;
x2 -> a32;
x2 -> a42;
x2 -> a52;
x3 -> a12;
x3 -> a22;
x3 -> a32;
x3 -> a42;
x3 -> a52;
a02 -> a13;
a02 -> a23;
a02 -> a33;
a02 -> a43;
a02 -> a53;
a12 -> a13;
a12 -> a23;
a12 -> a33;
a12 -> a43;
a12 -> a53;
a22 -> a13;
a22 -> a23;
a22 -> a33;
a22 -> a43;
a22 -> a53;
a32 -> a13;
a32 -> a23;
a32 -> a33;
a32 -> a43;
a32 -> a53;
a42 -> a13;
a42 -> a23;
a42 -> a33;
a42 -> a43;
a42 -> a53;
a52 -> a13;
a52 -> a23;
a52 -> a33;
a52 -> a43;
a52 -> a53;
a03 -> O1;
a13 -> O1;
a23 -> O1;
a33 -> O1;
a43 -> O1;
a53 -> O1;
a03 -> O2;
a13 -> O2;
a23 -> O2;
a33 -> O2;
a43 -> O2;
a53 -> O2;
a03 -> O3;
a13 -> O3;
a23 -> O3;
a33 -> O3;
a43 -> O3;
a53 -> O3;
a03 -> O4;
a13 -> O4;
a23 -> O4;
a33 -> O4;
a43 -> O4;
a53 -> O4;
}
I don't think changing the labels is a good solution.
If the ordering of the nodes within each layer is important, I suggest adding invisible edges within each layer, forcing the order of the nodes.
Something like this:
digraph G {
rankdir = LR;
splines=false;
edge[style=invis];
ranksep= 1.4;
{
rank=same;
x0->x1->x2->x3;
}
{
rank=same;
a0->a1->a2->a3->a4;
}
{
rank=same;
b0->b1->b2->b3->b4;
}
{
rank=same;
c0->c1->c2->c3;
}
edge[style=solid, tailport=e, headport=w];
{x0; x1; x2; x3} -> {a0;a1;a2;a3;a4};
{a0;a1;a2;a3;a4} -> {b0;b1;b2;b3;b4};
{b0;b1;b2;b3;b4} -> {c0,c1,c2,c3};
}
So, I use some dirty tricks to get the following picture:
I connect all the nodes together with the following code like the following:
x0 -> a02 [style=invisible, dir=none];
I relabel the nodes text according to each nodes position displayed in the picture (this is the really dirty one)
So, my complete code is available at here.
Please let me know if there is any better solution to this issue.

Graphviz, How to center the arrow (make a straight line) between two nodes?

Currently, I have this plot which looks fine for me except for the arrow connecting X and Y directly.
This is the plot I'd like to draw where the arrow is about in the center, I had one solution which is to create an invisible node in the middle, but just wondering if there is a better way, since I feel it can be done easily.
Here are my codes:
digraph{
graph [rankdir=LR]
node [shape = plaintext]
{rank=same; X1;X2;X3;X4;X5}
X -> X1 -> Y;
X -> X2 -> Y;
X -> X3 -> Y;
X -> Y;
X -> X4[dir=back];
X -> X5[dir=back];
X4 -> Y;
X5 -> Y;}
Graphviz tries to keep nodes on a straight line in rank direction if nodes belong to the same group.
digraph{
graph [rankdir=LR]
node [shape = plaintext]
X1;X2;X3
X[group=mid_straight];
Y[group=mid_straight];
X4;X5;
X -> X1 -> Y;
X -> X2 -> Y;
X -> X3 -> Y;
X -> Y;
X -> X4[dir=back];
X -> X5[dir=back];
X4 -> Y;
X5 -> Y;
}
if you want to have straight lines setting splines might be sufficient
digraph{
graph [rankdir=LR splines=line]
node [shape = plaintext]
{rank=same; X1;X2;X3;X4;X5}
X -> X1 -> Y;
X -> X2 -> Y;
X -> X3 -> Y;
X -> Y;
X -> X4[dir=back];
X -> X5[dir=back];
X4 -> Y;
X5 -> Y;
}

Resources