How to keep the graph form when adding new arrows? - graphviz

I have a graph like this:
Question 1: Is there a way to align the two columns horizontally in the top?
If I want to have an arrow a5 -> a1, then the graph would be:
Question 2: Is there a way to keep the graph as clean as before?
Here is the code:
digraph {
rankdir="LR";
// overlap=false;
nodesep="0.2";
ranksep="0.4";
fontsize = 25
labelloc="t";
fontname="Lato";
node [ shape="plaintext" style="filled, rounded" fontname="Lato" margin=0.2 ]
edge [ fontname="Lato" color="#2B303A" ]
subgraph cluster_0 {
style=filled;
color=lightgrey;
label = "Column 1";
fontsize = 20
node [style=filled,color=white];
a1
a2
a3
a4
a5
}
subgraph cluster_1 {
node [style=filled];
color=blue
label = "Column 2";
fontsize = 20
// labeljust=r
// labelloc=b
b1
b2
b3
b4
}
a1 -> b1
b1 -> a2
a2 -> b2
b2 -> a3
a3 -> b3
b3 -> a4
a4 -> b4
b4 -> a5
a5 -> a1
}

Two minor steps are needed:
(1) Put all a nodes in the same rank. If you don't, graphviz establishes a hierarchical relationship between a1 and a5, that's what your graph shows.
(2) Add some extra weight to the edge between a1 and b1, to keep it straight.
digraph {
rankdir="LR";
// overlap=false;
nodesep="0.2";
ranksep="0.4";
fontsize = 25
labelloc="t";
fontname="Lato";
node [ shape="plaintext" style="filled, rounded" fontname="Lato" margin=0.2 ]
edge [ fontname="Lato" color="#2B303A" ]
subgraph cluster_0 {
style=filled;
color=lightgrey;
label = "Column 1";
fontsize = 20
node [style=filled,color=white];
{rank = same; a1 a2 a3 a4 a5 } // !!!
}
subgraph cluster_1 {
node [style=filled];
color=blue
label = "Column 2";
fontsize = 20
// labeljust=r
// labelloc=b
b1
b2
b3
b4
}
a1 -> b1[ weight = 10 ]; // !!!
b1 -> a2
a2 -> b2
b2 -> a3
a3 -> b3
b3 -> a4
a4 -> b4
b4 -> a5
a5 -> a1
}
now produces

I'd go about this with the two following changes:
Use constraint=false in order to not have the edge from a5 to a1 mess up the graph
use the group attribute to suggest straight edges between nodes (same attribute value for nodes that should be placed in a straight line when connected with an edge)
digraph {
rankdir="LR";
// overlap=false;
nodesep="0.2";
ranksep="0.4";
fontsize = 25
labelloc="t";
fontname="Lato";
node [ shape="plaintext" style="filled, rounded" fontname="Lato" margin=0.2 ]
edge [ fontname="Lato" color="#2B303A" ]
subgraph cluster_0 {
style=filled;
color=lightgrey;
label = "Column 1";
fontsize = 20
node [style=filled,color=white];
a1 [group=1]
a2
a3
a4
a5
}
subgraph cluster_1 {
node [style=filled];
color=blue
label = "Column 2";
fontsize = 20
// labeljust=r
// labelloc=b
b1 [group=1]
b2
b3
b4
}
a1 -> b1
b1 -> a2
a2 -> b2
b2 -> a3
a3 -> b3
b3 -> a4
a4 -> b4
b4 -> a5
a5 -> a1 [constraint=false]
}

Related

strictly left to right orthogonal arcs in 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:

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;
}

graphviz - how to create labels over straight arrows

Maybe I'm trying to bend graphviz more than I should, but would it
be possible to straighten the arrows? I need the labels to be over the arrow, not to the side as with label/xlabel; I'm using boxes to hold what is essentially label text, since using labels on the edges seems to lead to whacky behavior when the labels are long.
digraph G {
node [shape=rect style=filled
fontcolor=white fontsize=12 fontname="Helvetica Bold"]
edge [style=solid color="#777777"]
// introduce nodes; set fill
a1, a2, a3 [fillcolor="#438dd5"]
c1 [fillcolor="#08427b"]
b1, b2, b3 [fillcolor=white fontcolor=black fontname="Helvetica" shape=plain]
a1 -> b1[dir=none]
a2 -> b2[dir=none]
a3 -> b3[dir=none]
b1 -> c1
b2 -> c1
b3 -> c1
{ rankdir=LR rank=same a1 a2 a3 }
{ rankdir=LR rank=same b1 b2 b3 }
{ rankdir=LR rank=same c1 }
}
What I get:
What I want:
I usually do it using tables with no borders and white background instead of labels. You would probably also need to use headlabel or taillabel, because in this case you can precisely control their position with labeldistance and labelangle:
digraph G {
node [shape=rect style=filled
fontcolor=white fontsize=12 fontname="Helvetica Bold"]
graph [ranksep=1]
edge [style=solid color="#777777"]
a1 [fillcolor="#438dd5"]
a2 [fillcolor="#438dd5"]
a3 [fillcolor="#438dd5"]
c1 [fillcolor="#08427b"]
a1 -> c1 [
labeldistance=5
labelangle=0
headlabel=<
<table bgcolor="white" border="0">
<tr>
<td>b1</td>
</tr>
</table>
>
]
a2 -> c1 [
labeldistance=4
labelangle=0
headlabel=<
<table bgcolor="white" border="0">
<tr>
<td>b2</td>
</tr>
</table>
>
]
a3 -> c1 [
labeldistance=5
labelangle=0
headlabel=<
<table bgcolor="white" border="0">
<tr>
<td>b3</td>
</tr>
</table>
>
]
}
result:

graphviz: dotted box around "same"-grouped boxes

I have a number of boxes that are put on the same level as such:
via multiple {rank=same a3 b3_1 b3_2 c3_1 c3_2 d3_1 d3_2}; lines whereas I define my elements with a3 [label = "Assigned"]; lines.
I'd like to get a (dotted, if possible) box around all elements that are on the same level, as such (mockup via editor):
The whole source looks as follows:
digraph customer {
layout=dot
label = "some diagram";
labelloc = "t"; // place the label at the top
node [shape=record];
{rank=same a1 b1 c1 d1};
{rank=same a2 b2 c2 d2};
{rank=same a3 b3_1 b3_2 c3_1 c3_2 d3_1 d3_2};
{rank=same a4 b4_1_1 b4_1_2 b4_2_1 b4_2_2 c4_1_1 c4_1_2 c4_2_1 c4_2_2 d4_1_1 d4_1_2 d4_2_1 d4_2_2};
{rank=same a5 b5_1 b5_2 b5_3 b5_4 c5_1 c5_2 c5_3 c5_4 d5_1 d5_2 d5_3 d5_4};
{rank=same a6 b6_1 b6_2 b6_3 b6_4 c6_1 c6_2 c6_3 c6_4 d6_1 d6_2 d6_3 d6_4};
a1 [label = "Level 1"];
a2 [label = "Level 2"];
a3 [label = "Level 3"];
a4 [label = "Level 4"];
a5 [label = "Level 5"];
a6 [label = "Level 6"];
a1 -> a2 -> a3 -> a4; a4 -> a5 [label = "case ..." ]; a5 -> a6;
b1 [label = "Text A"];
b2 [label = "false"];
b3_1 [label = "no"];
b3_2 [label = "yes"];
b4_1_1 [label = "same"];
b4_1_2 [label = "different"];
b4_2_1 [label = "same"];
b4_2_2 [label = "different"];
b5_1 [label = "no", fillcolor = red, style=filled];
b5_2 [label = "no", fillcolor = red, style=filled];
b5_3 [label = "no", fillcolor = red, style=filled];
b5_4 [label = "yes", fillcolor = green, style=filled];
b6_1 [label = "yes", fillcolor = green, style=filled];
b6_2 [label = "yes", fillcolor = green, style=filled];
b6_3 [label = "yes", fillcolor = green, style=filled];
b6_4 [label = "yes", fillcolor = green, style=filled];
b1 -> b2;
b2 -> b3_1; b3_1 -> b4_1_1; b4_1_1 -> b5_1 [label = "A" ]; b5_1 -> b6_1;
b3_1 -> b4_1_2; b4_1_2 -> b5_2 [label = "B" ]; b5_2 -> b6_2;
b2 -> b3_2; b3_2 -> b4_2_1; b4_2_1 -> b5_3 [label = "C" ]; b5_3 -> b6_3;
b3_2 -> b4_2_2; b4_2_2 -> b5_4 [label = "D" ]; b5_4 -> b6_4;
subgraph clusterone {
a1; b1; c1; d1;
label="level 1";
graph[style=dotted];
}
c1 [label = "Text B"];
c2 [label = "true"];
c3_1 [label = "no"];
c3_2 [label = "yes"];
c4_1_1 [label = "same"];
c4_1_2 [label = "different"];
c4_2_1 [label = "same"];
c4_2_2 [label = "different"];
c5_1 [label = "no", fillcolor = red, style=filled];
c5_2 [label = "no", fillcolor = red, style=filled];
c5_3 [label = "yes", fillcolor = green, style=filled];
c5_4 [label = "yes", fillcolor = green, style=filled];
c6_1 [label = "yes", fillcolor = green, style=filled];
c6_2 [label = "yes", fillcolor = green, style=filled];
c6_3 [label = "yes", fillcolor = green, style=filled];
c6_4 [label = "yes", fillcolor = green, style=filled];
c1 -> c2;
c2 -> c3_1; c3_1 -> c4_1_1; c4_1_1 -> c5_1 [label = "E" ]; c5_1 -> c6_1;
c3_1 -> c4_1_2; c4_1_2 -> c5_2 [label = "F" ]; c5_2 -> c6_2;
c2 -> c3_2; c3_2 -> c4_2_1; c4_2_1 -> c5_3 [label = "G" ]; c5_3 -> c6_3;
c3_2 -> c4_2_2; c4_2_2 -> c5_4 [label = "H" ]; c5_4 -> c6_4;
d1 [label = "(else)"];
d2 [label = "???", fillcolor = yellow, style=filled];
d3_1 [label = "no"];
d3_2 [label = "yes"];
d4_1_1 [label = "same"];
d4_1_2 [label = "different"];
d4_2_1 [label = "same"];
d4_2_2 [label = "different"];
d5_1 [label = "no", fillcolor = red, style=filled];
d5_2 [label = "no", fillcolor = red, style=filled];
d5_3 [label = "no", fillcolor = red, style=filled];
d5_4 [label = "no", fillcolor = red, style=filled];
d6_1 [label = "yes", fillcolor = green, style=filled];
d6_2 [label = "yes", fillcolor = green, style=filled];
d6_3 [label = "yes", fillcolor = green, style=filled];
d6_4 [label = "yes", fillcolor = green, style=filled];
d1 -> d2;
d2 -> d3_1; d3_1 -> d4_1_1; d4_1_1 -> d5_1 [label = "I" ]; d5_1 -> d6_1;
d3_1 -> d4_1_2; d4_1_2 -> d5_2 [label = "J" ]; d5_2 -> d6_2;
d2 -> d3_2; d3_2 -> d4_2_1; d4_2_1 -> d5_3 [label = "K" ]; d5_3 -> d6_3;
d3_2 -> d4_2_2; d4_2_2 -> d5_4 [label = "L" ]; d5_4 -> d6_4;
}
By some reason it conflicts with rank=same declaration.
Try removing it and use cluster instead with rank=same inside, like this:
subgraph cluster_one {
label="cluster one";
rank=same;
style=dotted;
a1 b1 c1 d1
};
subgraph cluster_two {
label="cluster two";
rank=same;
style=dotted;
a2 b2 c2 d2
};
or even shorter (one line):
subgraph cluster_one { label="cluster one" rank=same style=dotted a1 b1 c1 d1 }
Keep in mind, that width of subgraphs will not be the same, as it used to be.

how to control edge placements and labels in dot (graphviz)

I have trouble controlling the layout of graphviz.
Trying to produce a simple automaton.
The source:
digraph mygraph {
rankdir=LR;
size="13,13"
node [shape = circle];
init -> Ready [ label = "" ];
Ready -> P1 [ label = "t<T\n----TexT----" ];
P1 -> Ready [ label = "t>T" ];
P1 -> B1 [ label = "t<T" ];
B1 -> P1 [ label = "----TexT----" ];
B1 -> U1 [ label = "----TexT----" ];
Ready -> P2 [ label = "t<T\n----TexT----" ];
P2 -> Ready [ label = "t>T" ];
P2 -> B2 [ label = "t<T" ];
B2 -> P2 [ label = "----TexT----" ];
B2 -> U2 [ label = "----TexT----" ];
U1 -> Ready [ label = "----TexT----", constraint=false];
U2 -> Ready [ label = "----TexT----", constraint=false];
P1 -> P2 [ label = "t<T\n----TexT----", constraint=false];
P2 -> P1 [ label = "t<T\n----TexT----", constraint=false];
}
trouble is, the labels are intertwined. I probably need:
1. larger spacing
2. move some of the edges up
3. control label placings
how do I do it?
Since the conflict occurs on vertical edges going in opposite directions between nodes placed by dot on the same rank (P1 & P2) you could use vertical rank direction (drop the "rankdir=LR" line) so that the labels for theses specific edges are placed one below the other rather than side by side.
Granted, it's not a universal cure for this sort of issues but should help here without unnecessarily bloating the graph (which increasing node separation via "nodesep" would do).

Resources