How to create a cyclic graph using GraphViz DOT? - dot

I tried to create a simple cyclic graph with this DOT input file:
digraph {
rankdir=LR;
node0 [label = "0", group="bottom"];
node1 [label = "1", group="bottom"];
node2 [label = "2", group="top"];
node3 [label = "3", group="top"];
node0 -> node1;
node1 -> node0;
node2 -> node3;
node3 -> node2;
}
and so far so good, it results in:
but now I want to have the following relationships added to the nodes:
node0 -> node3;
node3 -> node0;
node2 -> node1;
node1 -> node2;
and surprisingly, this results in:
If I remove rankdir=LR;, I get a vertical graph. I need a simple cyclic graph, since the node placement in space has a connection to what they relate to. So the new connections should be vertical, and the nodes should form a square. Is this possible to achieve using DOT?

It might be possible to achieve using DOT; I haven't played with it for a couple of years, so I'm a bit rusty. However, your data is rendered as a neat diamond if you use dot's sister program circo, which should be part of a normal GraphViz installation.

One way with dot would be to order the nodes in two rows:
digraph {
0 -> {1 3}
1 -> {0 2}
2 -> {3 1}
3 -> {2 0}
// Put specified nodes on same row:
{rank=same; 0; 1}
{rank=same; 2; 3}
}

Related

create fixed edge directional graphs in dot format with graphviz

Is there anyway to create defined fixed edges directional graphs using dot notation? the following dot notation (fig 2) generates an automated edges that are curved. It doesnt have notations which will generate directions with straight edges (fig 1). Been on hours trying to find anything close, any hints will be great. thank you.
# fig 1
box A --- box B
|. \
|. \
box C. \
box D
# fig 2
digraph G {
node [shape=record];
rankdir="BT"
a -> b [color = red][arrowhead = diamond][taillabel = "tail"]
b -> c [shape = box]
c -> a
}
Not sure what a fixed edge is, but if you don't want splines for edges, look at the splines attribute (https://graphviz.org/docs/attrs/splines/).
Here is you graph with splines=false. You can also try splines=polyline.
You might also connect the edges to specific ports on one or both of the nodes (https://graphviz.org/docs/attr-types/portPos/).
# fig 2
digraph G {
node [shape=record];
// see https://graphviz.org/docs/attrs/splines/
// also look at ports https://graphviz.org/docs/attr-types/portPos/
splines=false // or try splines=polyline
rankdir="BT"
a -> b [color = red][arrowhead = diamond][taillabel = "tail"]
b -> c [shape = box]
c -> a
}
Giving:

Ordering flowchart in graphviz

The graph I'd like to produce is a something like this a left-to-right flowchart with a main process at the top, and a series of groupings of stuff below that feed in and out at various points like this:
(though this is a dummy example and I want lots of stuff coming in and out from the top code box, which is why a horizontal layout works better than the default
The problem is that this is made in powerpoint...
I can get something close with this:
digraph example {
graph [
rankdir = LR
]
subgraph cluster_code {
label = "code";
A;
B;
C;
D;
}
subgraph cluster_data {
label = "data";
data_1;
data_2;
}
subgraph cluster_source {
label = "source"
source_1;
source_2
}
A -> B
B -> C
C -> D
data_1 -> A
data_2 -> B
A -> output_1
output_1 -> C
source_1 -> data_1
source_2 -> data_2
#{rank = same; source_2; data_2; A}
}
But if I try to bring the source and data clusters underneath the code cluster using {rank = same; source_2; data_2; A} (this is hashed out above, and I don't repeat the whole code for brevity of the post), I then A, data_2 and source_2 drop out of the box. I think this is something do do with rank and clusters not playing nicely together.
Any hints on getting something like the first graph above?
Am running graphviz via R/Rstudio and DiagrammeR.
It seems that you want to change "rankdir" in the middle of the graph. Quite reasonable, but Graphviz doesn't support it. Here is your graph, using default rankdir and the not-that-well-documented ability to effectively change rankdir by using rank=same in a subgraph. It also reverses edge arrowhead direction - a kludge, but it works.
digraph example {
node [width=1.5]
subgraph cluster_code {
label = "code";
{rank=same
A -> B -> C -> D
}
}
subgraph cluster_data {
label = "data";
data_1;
data_2;
}
subgraph cluster_source {
label = "source"
source_1;
source_2
}
A -> output_1
output_1 -> C
edge[dir=back minlen=2] // minlen makes (rank) space
A -> data_1 // -> A
A -> data_2 // -> A
edge[dir=back minlen=1]
data_1 -> source_1 // -> data_1
data_2 -> source_2 // -> data_2
}
Giving this:

How do I graph the Thompson's construction using graphviz?

I am trying to graph the construction of Thompson using graphviz, and I would like to know if anyone could help me graph one of the rules so that I can do the others.
I attach a reference image: https://en.wikipedia.org/wiki/Thompson%27s_construction#/media/File:Thompson-kleene-star.svg
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; s3;
node [shape = circle];
s0 -> s1 [ label = "ε" ];
s0 -> s3 [ label = "ε" ];
s1 -> s2 [ label = "ε" ];
s2 -> s1 [ label = "ε" ];
s2 -> s3 [ label = "ε" ];
}
Graphviz programs try to avoid placing nodes on top of other nodes. You can get the node placement by explicitly providing pos attributes for all the nodes. (Not that difficult, but a nuisance.) You can get neato to generate all straight edges, but you will have to provide the (spline) coordinates for all the arcs. Otherwise you get this:
As an alternative, instead of graphviz, if you use dpic or gpic, this program:
.PS
.defcolor pink rgb #FFC0CB
circlerad=circlerad*.8
## we need to place the large oval before we place nodes on it
Qx: circle invis ; line invis; circle invis; A: line invis;
ellipseht=ellipseht*2;
ellipsewid=ellipsewid*2
E:ellipse at A.c shaded "pink" " N(s)"
move to Qx.w
Q: circle "q" ; arrow "ε" ""; C1: circle ; A: line invis; C2: circle ; arrow "ε" ""; F: circle "f";
circlerad=circlerad*.8
F1:circle at last circle
move to E.n; up; P1: box invis "ε"
arc -> from C2.n to C1.n
arcrad=2
arc -> from Q.s to F.s
### gpic version of greek chars:
# move to E.s; down; box invis "" "\[*e]"
########################################
### dpic/svg version of greek chars
move to E.s; down; box invis "" "ε"
.PE
produced this:
gpic is part of the GNU (Linux) groff package.
dpic can be found here: https://ece.uwaterloo.ca/~aplevich/dpic/

Justify node text in DiagrammeR

Does anybody know if DiagrammeR currently supports left- and right-justification of node labels when using GraphViz?
Here is a quick example, where I would like to left-justify the text within both of the nodes:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\nBar']
B [label = 'Bar\nFoo']
A -> B
}
")
I was able to find one resource here for the native GraphViz that uses /l for left-justification, but when I try that within the grViz function I receive an error. For example:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\lBar']
B [label = 'Bar\lFoo']
A -> B
}
")
I appreciate any help in advance!
You need a double backslash to escape the first slash. Here are left and right justified labels:
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\\lBar\\l']
B [label = 'Bar\\rFoo\\r']
A -> B
}
")

Why is graphviz drawing two arrows, and using a weird order?

Why is graphviz drawing two arrows from uncap_spike to peel, and why is it drawing peel to the right of hang?
I want uncap_spike -> peel -> hang -> spike, in that order, with one edge between each.
alt text http://grab.by/33kA
digraph hangers {
compound=true
fontname="Gill Sans"
node [fontname="Gill Sans" shape=box fillcolor=white style="rounded, filled"]
edge [fontname="Gill Sans"]
subgraph cluster_prep {
style="filled"
label=Prep
gather [shape=Mrecord label="{gather | EtOH swab\nvented tubing}"]
uncap_bottle [label="uncap bottle"]
uncap_spike [label="uncap spike"]
swab [shape=Mrecord label="{swab EtOH | wait 30 seconds for sterility}"]
gather -> uncap_bottle -> swab -> uncap_spike
{rank=same gather uncap_bottle swab uncap_spike}
}
subgraph cluster_hang {
style=filled
label=Hang
{rank=same peel hang}
}
{rank=same uncap_spike -> peel -> hang -> spike -> prime}
hang -> rip [color=firebrick]
rip [label="eyelet\nripped" style="filled" shape=octagon regular fontcolor=white
fontsize=10 width=.5 fixedsize color=firebrick fillcolor=firebrick ]
swab -> not_sterile [color=firebrick]
not_sterile [label="not\nsterile" style="filled" shape=octagon regular fontcolor=white
fontsize=10 width=.5 fixedsize color=firebrick fillcolor=firebrick ]
}
I think that the rank=same might be confusing. Are you using it to keep everything horizontally? In that case there is an attribute (rankdir?) that you can apply to the entire graph instead.

Resources