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

shi*_*jin 31 graphviz networkx pygraphviz pyprocessing

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

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

例如我的图表:

strict digraph {
    1,2,3;
    1 -> 3;
    3 -> 2;
}
Run Code Online (Sandbox Code Playgroud)

产量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"];
}
Run Code Online (Sandbox Code Playgroud)

我得到的任何值相同的位置bb或者任意组合sizedpi.

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

有什么建议怎么做?

全文:

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

Rod*_*Rod 69

这是TL; DR版本:

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

dot -Tpng -Gsize=9,15\! -Gdpi=100 -ofoo.png foo.gv
Run Code Online (Sandbox Code Playgroud)

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

convert foo.png -gravity center -background white -extent 900x1500 final.png
Run Code Online (Sandbox Code Playgroud)

用空格填充图像,使其精确到 900×1500像素; 哪里convertImageMagick套件的一部分.

这是详细的解释:

澄清:

  1. bb属性被标记为"只写",因此Graphviz布局引擎在处理之前都不会尊重您提交的任何值.

  2. 在一般情况下,Graphviz可以生成矢量(可缩放)和位图图形,因此DPI并不总是有意义的度量.

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

你想要做的是有点复杂,因为Graphviz生成的图像的像素大小是由几个相互作用的属性驱动的.

我们以任意图形为例.

该命令gvgen? -dh3将生成三度的有向超立方体.(如果您想进一步了解更详细的gvgen的手册页的PDF再现是在这里,但它并不重要,它只是为了演示任意图).

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

gvgen -dh3 | dot -Tpng -oexample.png
Run Code Online (Sandbox Code Playgroud)

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

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

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

例如,运行:

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -oexample.png
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=200 -oexample.png
Run Code Online (Sandbox Code Playgroud)

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

因此,如果你想生成包含像素任意数量的图像,你需要同时设置sizedpi适当的.

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

gvgen -dh3 | dot -Tpng -Gsize=9,15\! -Gdpi=100 -oexample.png
Run Code Online (Sandbox Code Playgroud)

要么

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -oexample.png
Run Code Online (Sandbox Code Playgroud)

甚至:

gvgen -dh3 | dot -Tpng -Gsize=900,1500\! -Gdpi=1 -oexample.png
Run Code Online (Sandbox Code Playgroud)

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

这解决了大部分问题,但请注意,Graphviz仅缩放图像,直到其中一个尺寸与指定尺寸匹配.根据原始图像的纵横比,您可能会或可能不会得到您要查找的确切尺寸.

这是ratio属性发挥作用的地方.

命令:

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -Gratio=fill -oexample.png
Run Code Online (Sandbox Code Playgroud)

应该给你一个你正在寻找的精确尺寸的图像,但有一些注意事项:

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

  • 为此,Graphviz必须在每个维度中独立地缩放布局.它足够智能来缩放布局而不是图像,因此图像本身不会失真,但根据您所要求的宽高比与布局的"自然"宽高比的差异,水平与垂直间距可能看起来有点奇怪的.

ratio也接受一些不同的价值观.请参阅文档和/或进行一些实验以了解它们的作用.

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

convert in.png -gravity center -background white -extent 900x1500 out.png
Run Code Online (Sandbox Code Playgroud)

通过根据需要填充水平或垂直尺寸,将图像(从in.png)居中在900 x 1500像素的画布上(将其保存到out.png)