Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graphviz .dot node ordering

Tags:

graphviz

dot

I'm building a epsilon NFA to recognize a regular expression using the canonical construction. I'm using subgraphs to group various parts of the regular expression. The * operator is giving me particular trouble since dot has decided to move the order of the nodes around. I've tried adding edge weights to force particular edges to be short to keep the order of the edges in line but that does not seem to be working.

What I would like to do is force the nodes in a subgraph in to be placed in a particular order so that the output graph is recognizable as a particular type of (well known) construction. In the example below I would like edges 3, 4, 5 and 6 placed in that order, however the dot places them in the order 6, 3, 4, 5. Any pointers appreciated.

Note that the current weight parameter produces no difference than no weight parameter at all.

I have the following

digraph G {     rankdir = LR;     node [shape = none];             0 [label = "start"];     node [shape = circle];             1 [label = "q1"];             2 [label = "q2"];             3 [label = "q3"];             4 [label = "q4"];             5 [label = "q5"];     node [shape = doublecircle];             6 [label = "q6"];     subgraph re1 {             rank = same;             edge[label = "0"];             1 -> 2;     };     subgraph re2 {             rank = same;             edge[label = "ε"];                     3 -> 4 [weight = 10];             edge[label = "1"];                     4 -> 5 [weight = 10];             edge[label = "ε"];                     5 -> 6 [weight = 10];                     5 -> 4 [weight = 1];                     6 -> 3 [weight = 1];     };     edge[color=black];             0 -> 1     edge[label = "ε"];             2 -> 3; } 

graphiz output

like image 394
Michael Conlen Avatar asked Oct 02 '11 17:10

Michael Conlen


People also ask

What is the Order in which nodes appear in a graph?

If ordering="in", then the inedges of a node must appear left-to-right in the same order in which they are defined in the input. If defined as a graph or subgraph attribute, the value is applied to all nodes in the graph or subgraph.

How to use GraphViz (dot)?

Graphviz (dot) examples Some examples on how to use Graphviz. If the shape attribute is set to record, the text of the label is layouted in tabular form. The vertical bar (|) starts a new row or column. The curly braces { ... } change (flip) the direction of |. Normally, a dependency (an edge) is declared with an arrow: Node1 -> Node2.

What is the difference between node () and edge () methods in GraphViz?

The node () method takes a name identifier as first argument and an optional label . The edge () method takes the names of start node and end node, while edges () takes an iterable of name pairs. Keyword arguments are turned into (node and edge) attributes (see extensive Graphviz docs on available attributes ).

What happens if I unset the xdot version in GraphViz?

If unset, graphviz will set this attribute to the xdot version used for output. External label for a node or edge. For nodes, the label will be placed outside of the node but near it. For edges, the label will be placed near the center of the edge.


1 Answers

Here's how I'd write that graph:

  • First of all, to me this is a graph which goes from top to bottom, not left to right, therefore I removed the rankdir=LR and added rank=same only for nodes 0/1 and nodes 2/3.
  • I removed all the weights
  • Most importantly, I added constraint=false to the edges going against the direction of the graph - the one going from node 4 to node 5, and the one from node 6 to node 3.

Here the source:

digraph G {     0 [label = "start", shape = none];      node [shape = circle];     1 [label = "q1"];     2 [label = "q2"];     3 [label = "q3"];     4 [label = "q4"];     5 [label = "q5"];     6 [label = "q6", shape = doublecircle];      {rank = same; 0 -> 1; }     1 -> 2 [label = "0"];     {rank = same; 2 -> 3 [label = "ε"]; }     4 -> 5 [label = "1"];     edge [label = "ε"];     3 -> 4;     5 -> 6;     5 -> 4 [constraint = false];     6 -> 3 [constraint = false]; } 

And here's the result:

graphviz output

Now if you want to, you could keep rankdir=LR, just take the markup you posted, remove the weights and add constraint=false to the same edges as I did, it works, too.

like image 160
marapet Avatar answered Oct 11 '22 13:10

marapet