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:
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)
I have a following code from .dot file:
digraph "fowchart" {
p1 [shape=point,label="",fixedsize=true,width=0.1,xlabel="Channel.fromFilePairs"];
p2 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="ifEmpty"];
p1 -> p2;
p2 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="ifEmpty"];
p3 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="map"];
p2 -> p3;
p3 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="map"];
p4 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="separate"];
p3 -> p4;
p4 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="separate"];
p5 [shape=point];
p4 -> p5 [label="bim_ch"];
p4 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="separate"];
p6 [label="maf"];
p4 -> p6 [label="raw_ch"];
p6 [label="maf"];
p7 [label="iteratCallRate"];
p6 -> p7 [label="qc1"];
p7 [label="iteratCallRate"];
p9 [label="HWEfilt"];
p7 -> p9 [label="qc2"];
p7 [label="iteratCallRate"];
p8 [label="checkIfMissingDroped"];
p7 -> p8 [label="qc2_A"];
p9 [label="HWEfilt"];
p10 [label="pruningLD"];
p9 -> p10 [label="qc3"];
p10 [label="pruningLD"];
p11 [label="PCA"];
p10 -> p11 [label="qc4"];
p10 [label="pruningLD"];
p11 [label="PCA"];
p10 -> p11 [label="qc4_PCA"];
p11 [label="PCA"];
p14 [label="heteroziogistyTes"];
p11 -> p14 [label="qc5_PCA"];
p11 [label="PCA"];
p14 [label="heteroziogistyTes"];
p11 -> p14 [label="qc5"];
p11 [label="PCA"];
p13 [shape=point];
p11 -> p13 [label="outliers_pca_evec"];
p11 [label="PCA"];
p12 [shape=point];
p11 -> p12 [label="PC_for_cov"];
p14 [label="heteroziogistyTes"];
p17 [label="plink"];
p14 -> p17 [label="qc6"];
p14 [label="heteroziogistyTes"];
p15 [shape=point];
p14 -> p15 [label="qc6_LD"];
p14 [label="heteroziogistyTes"];
p36 [label="filterByInfo"];
//p14 -> p36 [label="sample"];
p16 [shape=point,label="",fixedsize=true,width=0.1];
p17 [label="plink"];
p16 -> p17;
p17 [label="plink"];
p19 [label="shapeitCheck"];
p17 -> p19 [label="plinkOutChan"];
p18 [shape=point,label="",fixedsize=true,width=0.1];
p19 [label="shapeitCheck"];
p18 -> p19 [label="db_path"];
p19 [label="shapeitCheck"];
p21 [label="shapeit"];
p19 -> p21 [label="shapitCheckChan"];
p20 [shape=point,label="",fixedsize=true,width=0.1];
p21 [label="shapeit"];
p20 -> p21 [label="db_path"];
p21 [label="shapeit"];
p22 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="flatMap"];
p21 -> p22 [label="shapeitChan"];
p22 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="flatMap"];
p24 [label="impute2"];
p22 -> p24 [label="imputeChromChunckChannel"];
p23 [shape=point,label="",fixedsize=true,width=0.1];
p24 [label="impute2"];
p23 -> p24 [label="db_path"];
p24 [label="impute2"];
p25 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toSortedList"];
p24 -> p25 [label="impute2Chan"];
p24 [label="impute2"];
p27 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toSortedList"];
p24 -> p27 [label="impute2Chan2"];
p25 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toSortedList"];
p26 [shape=point];
p25 -> p26;
p27 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toSortedList"];
p28 [shape=point];
p27 -> p28;
p29 [shape=point,label="",fixedsize=true,width=0.1];
p30 [label="impute2Concat"];
p29 -> p30 [label="impute2MapChannel"];
p30 [label="impute2Concat"];
p33 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toList"];
p30 -> p33 [label="addedChrNum"];
p31 [shape=point,label="",fixedsize=true,width=0.1];
p32 [label="impute2Concat2"];
p31 -> p32 [label="impute2MapChannel2"];
p32 [label="impute2Concat2"];
p34 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toList"];
p32 -> p34 [label="addedChrNum_info"];
p33 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toList"];
p35 [label="mergeChromosomes"];
p33 -> p35;
p34 [shape=circle,label="",fixedsize=true,width=0.1,xlabel="toList"];
p35 [label="mergeChromosomes"];
p34 -> p35;
p35 [label="mergeChromosomes"];
p36 [label="filterByInfo"];
p35 -> p36 [label="genome"];
p35 [label="mergeChromosomes"];
p36 [label="filterByInfo"];
p35 -> p36 [label="genome_info"];
p36 [label="filterByInfo"];
p37 [label="postImpQC"];
p36 -> p37 [label="plink_post_imp"];
p37 [label="postImpQC"];
p38 [label="associationTest"];
p37 -> p38 [label="chrposa1a2"];
p37 [label="postImpQC"];
p40 [label="PRS"];
p37 -> p40 [label="chrposa1a2_forPRS"];
p38 [label="associationTest"];
p39 [label="gwasGraphs"];
p38 -> p39 [label="GWAS_results"];
}
Which generates the following .png image:
Is there an easy way to edit code to at least make it one continuous graph?
This is a general output from nextflow pipeline making tool, thus would be quite useful for many (i don't consider q to be too specific thus).
I am trying to plot a finite state transducer in GraphViz. I already have the self-loops defined, but when I plot them, I cannot get a nice "flower"-like distribution of loops around the main node.
digraph G {
size="8,5"
splines=true;
nodesep=1.0;
node [shape=ellipse,width=1,height=1];
0 [peripheries=2];
0:n -> 0:n [label=" A:A" minlen=5.0 rotate=45]
0:ne -> 0:ne [headlabel=" A:B" minlen=5.0];
0:e -> 0:e [label=" B:A" minlen=5.0];
0:se -> 0:se [label=" B:A" labeldistance=-8 minlen=5.0];
0:s -> 0:s [label=" *e*:A" minlen=5.0];
0:sw -> 0:sw [label=" *e*:B" minlen=5.0];
0:w -> 0:w [label=" B:*e*" minlen=5.0];
0:nw -> 0:nw [label=" A:*e*" minlen=5.0];
overlap=false
}
My plot looks like the following
Is there a way I can rotate the edge orientation of the self-loops originating and terminating at NW, SE, SW, NE? I have tried the orientation and rotate commands, but I cannot get them to work in dot and neato.
I'm pretty sure this is not the answer you want, but it does answer your question.
As you can see, Graphviz has a sort of "perpendicular" approach when drawing the loops, i.e. it favors a horizontal or vertical major direction. I don't think you can avoid it.
That said, here is how to transform your graph into an orchid-like distribution of loops around the main node:
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="http://viz-js.com/bower_components/viz.js/viz-lite.js"></script>
<script src="https://github.com/magjac/d3-graphviz/releases/download/v0.1.2/d3-graphviz.min.js"></script>
<div id="graph" style="text-align: center;"></div>
<script>
var dots = [
`
digraph G {
size="8,5"
splines=true;
nodesep=1.0;
node [shape=ellipse,width=1,height=1, orientation=22.5, group="hej"];
0 [peripheries=2];
0:n -> 0:n [id=1 label=" A:A" minlen=0.0 rotate=45];
0:ne -> 0:ne [id=2 headlabel=" A:B" minlen=0.0];
0:e -> 0:e [id=3 label=" B:A" minlen=0.0];
0:se -> 0:se [id=4 label=" B:A" labeldistance=-8 minlen=0.0];
0:s -> 0:s [id=5 label=" *e*:A" minlen=0.0];
0:sw -> 0:sw [id=6 label=" *e*:B" minlen=0.0];
0:w -> 0:w [id=7 label=" B:*e*" minlen=0.0];
0:nw -> 0:nw [id=8 label=" A:*e*" minlen=0.0];
overlap=false
}
`, `
digraph G {
size="8,5"
splines=true;
nodesep=1.0;
node [shape=ellipse,width=1,height=1, orientation=22.5, group="hej"];
0 [peripheries=2];
0:n -> 0:n [id=1 label=" A:A" minlen=0.0 rotate=45];
0:nw -> 0:ne [id=2 headlabel=" A:B" minlen=0.0];
0:e -> 0:e [id=3 label=" B:A" minlen=0.0];
0:ne -> 0:se [id=4 label=" B:A" labeldistance=-8 minlen=0.0];
0:s -> 0:s [id=5 label=" *e*:A" minlen=0.0];
0:se -> 0:sw [id=6 label=" *e*:B" minlen=0.0];
0:w -> 0:w [id=7 label=" B:*e*" minlen=0.0];
0:sw -> 0:nw [id=8 label=" A:*e*" minlen=0.0];
overlap=false
}
`
];
var dotIndex = 0;
var graphviz = d3.select("#graph").graphviz();
function render() {
var dot = dots[dotIndex % dots.length];
var transition1 = d3.transition()
.delay(1000)
.duration(1000 + 4000 * dotIndex);
graphviz
.tweenShapes(false)
.engine("dot")
.keyMode("id")
.dot(dot)
.transition(transition1)
.render();
dotIndex += 1;
transition1
.transition()
.duration(0)
.on('end', function () {
if (dotIndex != dots.length) {
render();
}
});
}
render();
</script>
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;
}