What is the purpose of the -n2 option with neato?


I would like to understand what is the purpose of the option -n2 of the neato command .
Indeed, based on gvpack doc

  • Acceptable input is produced by applying a Graphviz layout program, such as dot or neato, with no -T flag.
  • The output of gvpack can be used to produce concrete output by applying neato -s -n2 with the desired -T flag.

My version :

$ dot -V
dot - graphviz version 2.50.0 (20211204.2007)
$ cat D.dot
digraph D {
n0 -> {n1  n2  n3} ;
$ cat N.dot
digraph N {
xn0 [ pos = "0,0!" label="n0" ];
xn1 [ pos = "2,0!" label="n1" ];
xn2 [ pos = "2,1!" label="n2" ];
xn3 [  label="n3" ];
xn0 -> {xn1  xn2  xn3} ;

$ dot D.dot > D-o.dot & neato N.dot > N-o.dot

$ gvpack -array_i2 D-o.dot N-o.dot | tee pack.dot | neato -n2 -Tdot | tee pack2.dot | neato -n2 -Tsvg > pack.svg

But :

$ comm -3 pack.dot pack2.dot

…the two output pack file are identicall.

so finally why :

$ neato -n2 pack.dot -Tsvg > pack.svg

gives this ?



$ neato pack.dot -Tsvg > pack.svg

gives that ?

Thanks !

First, the -n (or -n1) option: Somehow, you have pos values (in points) for all the nodes, and just want neato to draw the edges FAQ | Graphviz
The -n2 option is used when you have all the node pos values and all the edge pos values and just want neato to convert to a different output format FAQ | Graphviz
Because it is more difficult to create or modify edge pos values (splines) (e.g. see Fun with edges!), neato -n is probably more commonly used.
Neato without the -n/-n2 options uses its own placement algorithm(s) and will produce very different results. (https://graphviz.org/pdf/neatoguide.pdf)
Note that neato -n is similar to, but not the same as, pinning node pos values (pin | Graphviz)

So it’s more a d3-graphviz question now…I don’t know if this feature ( specifying option ) is implemented yet.

I was wondering what to do to get the right result

the -n2 is mandatory here as everything is already computed…


for any engine (dot, neato, …) you can set layout=nop2 (as a root graph attribute). Seems to work the same as neato -n2

1 Like

nop2 !!! This is REALLY useful for me!

thanks again.

This is more a historical note than a practical post. At some point, we realized it would be valuable to supply a separate rendering phase, separate from layout. One could then take a graph with coordinate information, perhaps edit it, and then generate an image. For some reason, this phase was made part of neato, perhaps because it contained a lot of the common post-processing functions available for the non-dot layouts. This probably should have been done as a distinct layout, and the common post-processing code in neato (edge drawing, node overlap removal, etc.) should have been moved to lib/common.

Separately, John developed the plug-in architecture. This meant that all of the layout programs shared a common main() routine, with the layout algorithm determined by the command name, the “layout” attribute or the -K flag. (In essence, -Kxxx is equivalent to -Glayout=xxx.)

Note that graphviz output coordinates are in points, but historically neato and fop read in coordinates in inches. This means if you feed coordinates generated by graphviz into neato or fdp, you probably need the -s flag. This became such a nuisance with neato -n that we made one of the few major backward incompatible changes in graphviz, and dropped the need for -s when used with neato -n[2].

A quick glance indicates a lot of holes about this topic in the documentation. For example, the layouts “nop” and “nop2” are not listed under Layout Engines; I think the only description occurs in the library manual. Also, the documentation should stress that nop2 does not require all edges to have a layout. Any edges missing a drawing will be given one based on the splines attribute.