Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graphviz ignores size attribute (A4 page)

Tags:

graphviz

Consider the following minimal example graph that should fit on an A4 page

digraph G{
size="8.3,11.7!" ratio=fill;
foo->bar;
}

Compile with neato -Tpdf -o min_ex.pdf min_ex.gv The resulting pdf file has dimensions of 236mm x 115mm and not, as intended, 210mm x 297mm.

Graphviz ignores this attribute both for graphs that are smaller than the page (like this one) and the ones that have to be scaled down to fit.

I have tried any combinations of size and ratio attributes, I can't get the graph to be put on an A4 page with any of them.

So, what have I to specify that the graph is always put on an A4 page, regardless of its size?

Documentation:

size:

Maximum width and height of drawing, in inches. If only a single number is given, this is used for both the width and the height.

If defined and the drawing is larger than the given size, the drawing is uniformly scaled down so that it fits within the given size.

If size ends in an exclamation point (!), then it is taken to be the desired size. In this case, if both dimensions of the drawing are less than size, the drawing is scaled up uniformly until at least one dimension equals its dimension in size.

ratio

Sets the aspect ratio (drawing height/drawing width) for the drawing. Note that this is adjusted before the size attribute constraints are enforced. In addition, the calculations usually ignore the node sizes, so the final drawing size may only approximate what is desired.

If ratio is numeric, it is taken as the desired aspect ratio. Then, if the actual aspect ratio is less than the desired ratio, the drawing height is scaled up to achieve the desired ratio; if the actual ratio is greater than that desired ratio, the drawing width is scaled up.

If ratio = "fill" and the size attribute is set, node positions are scaled, separately in both x and y, so that the final drawing exactly fills the specified size. If both size values exceed the width and height of the drawing, then both coordinate values of each node are scaled up accordingly. However, if either size dimension is smaller than the corresponding dimension in the drawing, one dimension is scaled up so that the final drawing has the same aspect ratio as specified by size. Then, when rendered, the layout will be scaled down uniformly in both dimensions to fit the given size, which may cause nodes and text to shrink as well. This may not be what the user wants, but it avoids the hard problem of how to reposition the nodes in an acceptable fashion to reduce the drawing size.

If ratio = "compress" and the size attribute is set, dot attempts to compress the initial layout to fit in the given size. This achieves a tighter packing of nodes but reduces the balance and symmetry. This feature only works in dot.

If ratio = "expand", the size attribute is set, and both the width and the height of the graph are less than the value in size, node positions are scaled uniformly until at least one dimension fits size exactly. Note that this is distinct from using size as the desired size, as here the drawing is expanded before edges are generated and all node and text sizes remain unchanged.

If ratio = "auto", the page attribute is set and the graph cannot be drawn on a single page, then size is set to an ``ideal'' value. In particular, the size in a given dimension will be the smallest integral multiple of the page size in that dimension which is at least half the current size. The two dimensions are then scaled independently to the new size. This feature only works in dot.

like image 760
J. Curwen Avatar asked Jul 18 '13 09:07

J. Curwen


1 Answers

The problem lies in the details about the ratio:

Note that this is adjusted before the size attribute constraints are enforced. In addition, the calculations usually ignore the node sizes, so the final drawing size may only approximate what is desired.

It seems that graphviz

  • lays out the nodes as points (ignoring size)
  • adjusts for the ratio of the point nodes (still no size for nodes)
  • applies the graph's size constraints (in our case, upscaling the image): here we have already reached the desired dimensions, but we're not finished...
  • then point nodes become nodes with a real size (by default 0.5 inch high and 0.75 inch wide)
  • and finally the whole output gets the margin added

The result would be bigger than A4.

Therefore if we were to make nodes and margin as small as possible, then the output should come relatively close to A4.

Setting margin to 0 and the node's shape to point as well as their width and height to the minimum values with the following graph:

digraph G{
 ratio="fill";
 size="8.3,11.7!";
 margin=0;

 node[shape=point, height=0.02, width=0.01];
 foo->bar;
}

neato -Tpdf with this graph results in a PDF with dimensions 211x297mm (using 8.267 inches as width will result in a clean 210x297mm).


Unfortunately, even knowing how graphviz works in respect to ratio=fill, I don't think there's an easy way to make sure the final result is always A4 when using nodes which actually have a width and height.

like image 52
marapet Avatar answered Nov 20 '22 03:11

marapet