Graphviz: Edge orientation to and from same node - graphviz

I'm creating some multilevel SEM graphs and I'm running into a small problem. The latent variable at the bottom of the graph (labeled "WF") is supposed to have a double-headed edge to and from it but the edge should go under the node. Note the correct orientation of the topmost node. Seems and easy fix but I can find it. Thanks in advance. (BTW, I've provided only a snippet of the original model, but this is sufficient for the purpose.)
digraph stackex {
{rank=min;
bf [shape=ellipse]
bf:nw -> bf:ne [dir = both]}
{node[shape=square]
bf -> i1
i1[label=X1]
i1 -> wf [dir=back]}
{wf [shape=ellipse]
wf:sw -> wf:se [dir = both]}
}
And here's what it produces:
The double-headed arrow should go under the node labled "WF".

Based on experimentation, it appears that the only way to get
wf:sw -> wf:se [dir = both]
to do what you want is to add
graph [rankdir=TB]
Unfortunately, rankdir affects the entire graph (not just a subgraph or cluster). So you can fix one loop, but you break the other.
The only way I've found to accomplish your goal is to hand-modify the pos of the offending edge (spline). This:
digraph stackex {
graph [bb="0,0,82.583,216"];
node [label="\N",
shape=square
];
bf [height=0.5,
pos="41.292,162",
shape=ellipse,
width=0.75];
bf:nw -> bf:ne [dir=both,
pos="s,26.292,177 e,56.292,177 22.277,186.17 18.135,200.16 21.792,216 41.292,216 60.792,216 64.448,200.16 60.306,186.17"];
i1 [height=0.5,
label=X1,
pos="41.292,90",
width=0.5];
bf -> i1 [pos="e,41.292,108.1 41.292,143.7 41.292,135.98 41.292,126.71 41.292,118.11"];
wf [height=0.5,
pos="41.292,18",
shape=ellipse,
width=0.75];
i1 -> wf [dir=back,
pos="s,41.292,71.697 41.292,61.665 41.292,53.054 41.292,43.791 41.292,36.104"];
wf:se -> wf:sw [dir=both,
pos="s,56.292,3 e,26.292,3
65.002,8.3185
92.908,0.389
88.823,-20
41.292,-20
-6.2395,-20
-10.324,0.389
17.582,8.3185"];
}
And this command
neato -n2 -Tpng doubleheaded3.fixed.dot >doubleheaded3.fixed.png
Gives this:
All in all, I'd suggest the pic/gpic/dpic language. Lower-level, but probably easier to use in the long run.

Related

In GraphViz, in a strict graph, is it possible to have 2 edges between nodes if they have different attributes?

What I want to achieve is, if I have something like
Strict Digraph G {
a -> b [label = edge1]
a -> b [label = edge2]
a -> b
a -> b
a -> b [label = edge1]
}
then I should get a graph with 2 nodes and 3 edges between them (One with label edge1, one with edge2 and one without a label).
It doesn't seem to be possible, with the strict keyword with this input, it only draws one edge.
Sorry, not "legal". From https://graphviz.org/doc/info/lang.html
A graph may also be described as strict. This forbids the creation of multi-edges, i.e., there can be at most one edge with a given tail node and head node in the directed case.

Invert edge trajectory graphviz

i am trying to graph a doubly linked circular list in .dot language but it does not display as i want. Both of the circular edges are under the nodes but i want 1 of them above
this is what i want:
expected result
but i get this instead:
given result
here is my .dot code: https://dreampuf.github.io/GraphvizOnline/#digraph%20{%0A%20%20node[shape=record];%0A%20%20graph[pencolor=transparent];%0A%20%20rankdir=LR;%0A%20%20p1[label=%22{%3Cprev%3E|%3Cdata%3E%2012|%3Cnext%3E}%22];%0A%20%20p2[label=%22{%3Cprev%3E|%3Cdata%3E%2012|%3Cnext%3E}%22];%0A%20%20p3[label=%22{%3Cprev%3E|%3Cdata%3E%2012|%3Cnext%3E}%22];%0A%0A%0A%20%20%20%20p1:next%20-%3E%20p2:prev;%0A%20%20p2:next%20-%3E%20p3:prev;%0A%20%20p2:prev%20-%3E%20p1:next;%0A%20%20p3:prev%20-%3E%20p2:next;%0A%20%20%20%20edge[tailclip=false,dir=%22forward%22%20splines=%22compound%22%20constraint=%20%22false%22];%0A%20%0A%20%0Ap3:next%20-%3E%20p1:prev;%0A%0Ap1:prev%20-%3E%20p3:data;%0A%0A%20%20%20%20%0A}
thank you
Main change was to add a port position (https://graphviz.org/docs/attr-types/portPos/) to the head & tail of the edge. Also removed some unneeded bits.
digraph {
node[shape=record];
graph[pencolor=transparent];
rankdir=LR;
p1[label="{<prev>|<data> 12|<next>}"];
p2[label="{<prev>|<data> 12|<next>}"];
p3[label="{<prev>|<data> 12|<next>}"];
p1:next -> p2:prev;
p2:next -> p3:prev;
p2:prev -> p1:next;
p3:prev -> p2:next;
p1:prev:n -> p3:data:n;
// edge[tailclip=false,dir="forward" splines="compound" constraint= "false"];
p3:next -> p1:prev;
}
Giving:

Change edge placement from beneath to above nodes in Graphviz

It took me some time to make the graph below look like it does right now, and I'm almost satisfied. The one thing that still bothers me is that the connection between D and B should be above all nodes for the sake of aesthetics.
The funny thing is, that supplying the ports for the edge doesn't impress dot which just makes the edge cross the connected nodes.
Do you have an idea on how to avoid this?
digraph {
graph [splines=ortho, nodesep=0.2, fontname="DejaVu Sans", rankdir=LR]
node [shape=box, fontsize=8]
edge [arrowsize=0.5]
subgraph cluster {
style=invis;
A -> B -> C;
A -> B -> C;
A -> B -> C -> D;
D -> E;
D:nw -> B:ne;
}
{
D -> F -> { C; E };
}
}
PS: You need the latest Graphviz version in order to get orthogonal edges.
It may be a function of the version of the engine you use. I'm not sure what version of dot the GraphViz Workspace http://graphviz-dev.appspot.com/ uses but it does run your problem connector across the top.

simple "T shaped" graph in graphviz

Need draw a graph with dot/graphviz like this image:
The texts can be above arrows, like graphviz does it. But how to achieve the T-layout? Need make a cluster for the top row?
This is one possibility using rank=same for a subgraph:
digraph g {
node[shape=point, width=0.2];
{
rank=same;
p1 -> n [label="text1"];
n -> p2 [label="text2"];
}
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
You could also use a left-right layout instead of top-down.
An other possibility is to disable the effect of some edges using constraint=false:
digraph g {
node[shape=point, width=0.2];
p1 -> n [label="text1", constraint=false];
n -> p2 [label="text2", constraint=false];
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
The result is the same.
dot usually layouts trees in layers. To force an edge to not be a layer separation you can add the constraint=false option. So something like:
digraph {
A [shape=point]
B [shape=point]
C [shape=point]
N [label="node"]
A -> N [label="text1", constraint=false]
N -> B [label="text2", constraint=false]
N -> C [label="text3", dir=back]
}
should work.
Note that the edge from the lower node to "node" has to be backwards, since dot layouts trees from top to bottom. Therefore the logical edge direction has to be from top to bottom, even though the display direction might be the other way round (which is the case here).

Right to left edges in dot (Graphviz)

I'm trying to display edges going from right to left (i.e. backwards) using dot:
C <- A -> B
The best I could do was:
digraph {
a -> b;
c -> a [dir="back"];
{rank=same;c a b}
}
..which is fine, except I don't like using c -> a when the edge is directed the other way.
So I wanted to share this solution (which didn't seem to be mentioned on SO) and check if I'm missing something obvious.
See: http://www.graphviz.org/doc/info/attrs.html#k:dirType
I have no alternative to your usage of dir, but i can make it slightly shorter, if you want horizontal alignment, use the rankdir property of graph, to force direction from left to right.
digraph {
rankdir=LR;
a->b;
c->a [dir="back"];
}
To make edges point backwards by default:
digraph {
edge [dir="back"];
a -> b;
c -> a;
}
Then, override the default to point forwards:
c -> d [dir="forward"];

Resources