Graphviz:强制集群之间不重叠

Graphviz: enforce nonoverlap among clusters

我正在尝试在同一个 .dot 文件中为一个研究项目生成几个无向图(树)的布局;目标是能够轻松地目视检查树木。为了实现这一点,我为每棵树制作了一个子图 cluster_,请参见示例:

graph {
layout = neato

subgraph cluster_0 {
label = "n= 7, tree 1";
nd_93 [label= "1"];
nd_94 [label= "2"];
nd_95 [label= "3"];
nd_96 [label= "4"];
nd_97 [label= "5"];
nd_98 [label= "6"];
nd_99 [label= "7"];
nd_93 -- nd_94;
nd_93 -- nd_97;
nd_94 -- nd_95;
nd_94 -- nd_96;
nd_97 -- nd_98;
nd_97 -- nd_99;
}
subgraph cluster_1 {
label = "n= 8, tree 1";
nd_238 [label= "1"];
nd_239 [label= "2"];
nd_240 [label= "3"];
nd_241 [label= "4"];
nd_242 [label= "5"];
nd_243 [label= "6"];
nd_244 [label= "7"];
nd_245 [label= "8"];
nd_238 -- nd_239;
nd_238 -- nd_243;
nd_239 -- nd_240;
nd_239 -- nd_241;
nd_239 -- nd_242;
nd_243 -- nd_244;
nd_243 -- nd_245;
}
subgraph cluster_2 {
label = "n= 9, tree 1";
nd_380 [label= "1"];
nd_381 [label= "2"];
nd_382 [label= "3"];
nd_383 [label= "4"];
nd_384 [label= "5"];
nd_385 [label= "6"];
nd_386 [label= "7"];
nd_387 [label= "8"];
nd_388 [label= "9"];
nd_380 -- nd_381;
nd_380 -- nd_385;
nd_381 -- nd_382;
nd_382 -- nd_383;
nd_382 -- nd_384;
nd_385 -- nd_386;
nd_386 -- nd_387;
nd_386 -- nd_388;
}
subgraph cluster_232 {
label = "n= 13, tree 1";
nd_20639 [label= "1"];
nd_20640 [label= "2"];
nd_20641 [label= "3"];
nd_20642 [label= "4"];
nd_20643 [label= "5"];
nd_20644 [label= "6"];
nd_20645 [label= "7"];
nd_20646 [label= "8"];
nd_20647 [label= "9"];
nd_20648 [label= "10"];
nd_20649 [label= "11"];
nd_20650 [label= "12"];
nd_20651 [label= "13"];
nd_20639 -- nd_20640;
nd_20639 -- nd_20648;
nd_20640 -- nd_20641;
nd_20640 -- nd_20645;
nd_20641 -- nd_20642;
nd_20641 -- nd_20643;
nd_20641 -- nd_20644;
nd_20645 -- nd_20646;
nd_20645 -- nd_20647;
nd_20648 -- nd_20649;
nd_20649 -- nd_20650;
nd_20649 -- nd_20651;
}
}

layout=dot 使树在水平线上彼此相邻出现,当树的数量超过四棵时,这是不可取的(在真实文件中大约有 300 棵)树)——找到模式变得更加困难。 .

layout=neato 在树本身的布局方面产生更好的结果(每个簇中的节点布局更忠实于无向树——dot 产生有根树的图)并且簇(实际的树)看起来靠得更近,可以更容易地进行目视检查。

但是,该布局在集群边界和标签(我需要查看以识别树木)之间产生严重的重叠。其他布局似乎效果更好,但不太正确:fdp 不会在簇边界产生重叠,但会产生边缘交叉。布局 sfdp 删除了集群边界并且完全不显示标签。

fdp: sfdp:

问题有人知道是否有一些布局选项,或者可能对选项进行一些微调layoutmodespline, ... 这样

  1. 集群重叠(如fdp),
  2. 树(单个簇)的布局不是有根树的布局(如 neato,而不是 dot),并且
  3. 没有边缘交叉(如 neatosfdp,而不是 fdp

簇在平面上可以任意排列,树(簇)n= 13, tree 1接近n= 13, tree 2暂时不重要(示例中没有出现) ).

你可以:

  • 在特殊目录中生成 (300) 个单独的图形,例如 graphs/。可能不再需要集群。假设刚刚创建的文件名的格式为 tree_nn_xxxxx.raw,其中 nn 是具有两位数字的节点数(0102、...)和 xxxxx是区分相同顶点数的图的索引; .raw 只是一个模拟扩展,能够从正则表达式 *.raw.

    中“捕获”它们
  • 运行 每个通过 neato(或任何引擎)。注意:使输出格式为-Tdot。例如,

for f in $(ls graphs/*.raw); do
    # '$f' contains '.raw'
    f_no_ext=${f:0: $(( ${#f} - 4 ))}
    dot -Tdot $f > $f_no_ext.dot
done
  • 然后,您可以使用 gvpack 将这些文件组合成一个(非常大的)图表。例如,
function normalize_value {
    n=
    if [ $n -lt 10 ]; then
        echo "0"$n
    else
        echo $n
    fi
}
for n in `seq 1 14`; do
    echo $n
    nn=$(normalize_value $n)
    gvpack -array_it20 graphs/tree_$nn*.dot > graphs/big_graph_$nn.dot
done

您可能想要 运行 使用 gvpack 进行一些实验以获得“最佳”布局。

  • 最后,运行 每个 big_graph_* 文件通过 neato -n2 -Tsvg 可视化结果。例如,
for n in `seq 1 14`; do
    echo $n
    nn=$(normalize_value $n)
    
    echo "    Run neato"
    neato -n2 -Tsvg graphs/big_graph_$nn.dot > all_trees_with_nonbip_$nn.svg
done