如何在GraphViz中设置点格式的输出大小?

时间:2013-02-09 02:44:38

标签: graphviz networkx pygraphviz pyprocessing

我想确保布局后所有节点都在某个范围内(比如[0,0,W,H])。

我认为边界框是使用bb属性的解决方案,但 dot neato 都只是覆盖它。

例如我的图表:

strict digraph {
    1,2,3;
    1 -> 3;
    3 -> 2;
}

neato -Gbb="0,0,50,50" -T dot file.txt的输出:

strict digraph {
        graph [bb="0,0,120.49,162.36"];
        node [label="\N"];
        1        [height=0.5,
                pos="27,18",
                width=0.75];
        3        [height=0.5,
                pos="70.233,75.918",
                width=0.75];
        1 -> 3   [pos="e,57.954,59.469 39.043,34.133 43.004,39.441 47.504,45.468 51.827,51.261"];
        2        [height=0.5,
                pos="93.485,144.36",
                width=0.75];
        3 -> 2   [pos="e,87.436,126.56 76.221,93.545 78.643,100.67 81.496,109.07 84.177,116.97"];
}

对于bb的任何值或sizedpi的任意组合,我都会获得相同的排名。

我需要的是在给定的框中包含所有节点。

有任何建议怎么做?

全文:

我正在使用来自 networkx 的* graphviz_layout *来布局我的图表。我用 pyprocessing 绘制图形。我想避免重新调整* graphviz_layout *的结果,如果有办法告诉neato我的界限。

1 个答案:

答案 0 :(得分:64)

这里是TL; DR版本:

要从foo.gv中的图形生成900 x 1500像素的PNG图像,您可以运行:

dot -Tpng -Gsize=9,15\! -Gdpi=100 -ofoo.png foo.gv

产生的图像正好是900像素宽或1500高,但不一定都是两者;然后:

convert foo.png -gravity center -background white -extent 900x1500 final.png

用空白填充图像,使其完全 900乘1500像素;其中convertImageMagick套件的一部分。

以下是详细解释:

澄清:

  1. The bb attribute is marked as "write-only",因此Graphviz布局引擎在处理之前都不会尊重您提交的任何值。

  2. 在一般情况下,Graphviz can generate both vector (scalable) and bitmap graphics,因此DPI并不总是有意义的指标。

    特别是,dpi属性仅对位图和SVG输出格式有效。

  3. 您尝试做的事情有点复杂,因为Graphviz生成的图像的像素大小是由几个相互作用的属性驱动的。

    让我们以任意图形为例。

    命令gvgen‎ -dh3将生成三级有向超立方体。 (如果你想了解更多细节,gvgen手册页的PDF版本是here,但它并不重要,它只是一个任意的图形用于演示目的。)

    可以通过运行命令来创建该图的默认点生成的PNG渲染:

    gvgen -dh3 | dot -Tpng -oexample.png
    

    当我这样做时,我得到一个275 x 347像素的PNG格式(位图)图像。 (据file example.png报道。)

    size属性可让您以英寸为单位推荐输出图像的最大或所需高度和宽度。即,属性size=3,5告诉Graphviz最多生成3 x 5英寸的图像 。如果图像开始时小于3乘5,Graphviz将不管它。如果图像开始时大于3英寸×5英寸,Graphviz会将其缩小,直到它适合3 x 5英寸的画布(保留原始图像的纵横比)。

    添加感叹号会将size属性从最大大小更改为所需的大小。现在,如果两个维度都小于指定的大小,则绘图将按比例放大,直到至少一个维度等于指定的大小。

    例如,运行:

    gvgen -dh3 | dot -Tpng -Gsize=3,5\! -oexample.png
    

    (注意\!转义了bash的感叹号。在DOT文件中,你只需要写size=3,5!。)

    生成一个288 x 363像素的图像,两个尺寸都略大于默认值。

    dot是如何得出这些数字的?好吧,Graphviz的默认DPI值是每英寸96像素。在该分辨率下,3×5 英寸图像是288×480 像素图像。布局引擎简单地放大图像,直到至少一个尺寸与所需尺寸匹配。

    您可以使用dpi attribute覆盖默认的DPI值,如下所示:

    gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=200 -oexample.png
    

    现在生成的图像测量600乘757像素。同样,Graphviz只是缩放图像直到其中一个尺寸与所需尺寸匹配(但在此分辨率下,3 x 5英寸图像是600 x 1000像素图像)。

    因此,如果要生成包含任意数量像素的图像,则需要适当地设置sizedpi

    即,假设您要创建900 x 1500像素的图像。你可以使用:

    gvgen -dh3 | dot -Tpng -Gsize=9,15\! -Gdpi=100 -oexample.png
    

    gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -oexample.png
    

    甚至:

    gvgen -dh3 | dot -Tpng -Gsize=900,1500\! -Gdpi=1 -oexample.png
    

    (虽然最后一个似乎在快速测试中对我有用,但为了以防万一,我建议坚持使用更传统的DPI值。)

    这解决了您的大多数问题,但请注意,Graphviz仅缩放图像,直到维度的一个与指定的大小匹配为止。根据原始图像的纵横比,您可能会或可能不会得到您要查找的确切尺寸。

    这是ratio attribute发挥作用的地方。

    命令:

    gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -Gratio=fill -oexample.png
    

    应该为您提供一个您正在寻找的精确尺寸的图像,但需要注意几点:

    • 在实践中,它似乎有时产生的尺寸略有不同。例如,当我运行上面的命令时,我得到一个900乘1472像素的图像(而不是900乘1500)。我不知道这是由于舍入错误还是什么原因。

    • 为实现此目标,Graphviz必须在每个维度中独立缩放布局。它足够聪明,可以缩放布局而非图像,因此图像本身并不会失真,但取决于您所要求的方面有多么不同比例来自布局"自然"纵横比水平与垂直间距可能看起来有点奇怪。

    ratio也接受一些不同的值。请参阅the documentation和/或进行一些实验,了解他们的工作。

    对于它的价值,如果你真的想要一张你要求的精确像素尺寸的图像,我的建议是让Graphviz缩放图像,使两个尺寸中的一个匹配,然后使用类似ImageMagick的内容来填充图像,以获得您正在寻找的精确宽高比。例如,命令:

    convert in.png -gravity center -background white -extent 900x1500 out.png
    

    将图像(来自in.png)置于900 x 1500像素画布上(将其保存到out.png),方法是根据需要填充水平或垂直尺寸