user2153235
user2153235

Reputation: 1115

GraphViz DOT output: What are the 4-6 "pos" coordinates for an "edge"

I just started to experiment with GraphViz's "neato" command for Kamada-Kawai graph visualization (solved using stress majorization). I am particularly interested in extracting the laid out node coordinates for external processing.

I was looking at this question to figure out the "pos" attribute for graph edges in the output DOT file. The attribute consists of 4 coordinate points. One helpful answer says that the series of coordinats (not necessarily 4) are the control points of a spline, likely a Bezier spline. The answerer is "compound eye", who I'll refer to as "CE". Here is the example given:

// digrfG.dot
//-----------
digraph G {

   A [label = "A"  xlabel="a" pos="0,100" ]
   B [label = "B"  xlabel="b" pos="100,0"]

   A -> B  [label = "A->B www"  xlabel="a->b"]
   [pos="0,100 0,0 0,0 100,0"]

}

In Bash, it is processed by GraphViz using:

# Make image:
#------------
dot -Kneato -n2 -Tpng digrfG.dot >| digrfG.png

# Make output DOT file:
#----------------------
dot -Kneato -n2       digrfG.dot >| digrfG_out.dot

The output is:

# digrfG_out.dot
#---------------
digraph G {
   graph [bb="-7,0,154,151"];
   node [label="\N"];
   A [height=0.5, label=A, pos="27,118",
      width=0.75, xlabel=a, xlp="-3.5,143.5"];
   B [height=0.5, label=B, pos="127,18",
      width=0.75, xlabel=b, xlp="96,43.5"];
   A -> B [label="A->B www", lp="42.5,75.5",
           pos="27,118 27,18 27,18 127,18",
           xlabel="a->b", xlp="63.5,60.5"];
}

My edge coordinates do not match CE's, neither in the numerical quantities nor in the number of coordinates. While I have 4 coordinates, CE has 6, including 2 coordinates at the start of the series prefixed by "s," and "e,". The Bezier curve page cited by CE gives the impression that typical Bezier splines have 4 control points, including start and end points, though the math allows for more. This Micrsoft page reinforces this impression of a 4-point default.

This GraphViz page shows that an edge's "pos" attribute contains a spline, starting with start and end points, prefixed with "s," and "e," as per CE's output, but the syntax is puzzling. If it is regular expression syntax, then there are 4 or more coordinates following optional start and end points. That might explain why I have no coordinates prefixed with "s," or "e,", but I have 4 coordinates.

In digrfG_out.dot above, if I compare the 4 coordinates with the node coordinates, it is clear that the first and last of the 4 coordinates match the node coordinates. It seems that CE's GraphViz defaults to 6 control points and explicitly designates start and end points at the head of the list of coordinates, whereas my GraphViz defaults to 4, without special treatment of the start and end points. Since GraphViz's spline page is so ambiguous, I was wondering if this interpretation can be confirmed.

Thanks.

Upvotes: 0

Views: 447

Answers (1)

sroush
sroush

Reputation: 6801

I would suggest skipping CE's explanation (not necessarily wrong, but maybe ambiguous) and go to the sources on the Graphviz website.
Yes, Bezier curves require 4 points per "segment" (my term) but the last point in a segment is also used as the first in the next segment. Graphviz's arrowheads use separate points - for one end of the arrowhead.

The optional s (start) and e (end) points are for optional arrowheads. Then 4 required points and then optional sets of 3 points. See p.36 https://www.graphviz.org/pdf/dotguide.pdf, https://forum.graphviz.org/t/how-to-control-the-points-of-splines/1087, and https://forum.graphviz.org/t/fun-with-edges/888 - in addition to the (yes, regular expression) http://www.graphviz.org/docs/attr-types/splineType/
I hope this helps.

Any edge can have arrowheads, even in a non-directed graph. Digraph just sets the default (arrowhead or no arrowhead). The dir attribute (https://graphviz.org/docs/attrs/dir/) explicitly sets arrowheads.
Finally, arrowhead shape (https://graphviz.org/doc/info/arrows.html) can be "none".

graph {
  A--B [dir=forward]
  C--D [dir=back]
  E--F [dir=both]
  G--H [dir=none]
}

Dot produces this:
enter image description here

Upvotes: 1

Related Questions