Force graphviz to preserve node positions

陌路散爱 提交于 2019-12-03 03:16:02

Graphviz doesn't make it easy to keep noes in the same position:

  • Adding/removing a node can cause a completely different layout.
  • Adding/removing a node can change the dimension of the bounding box to change.

The following works if all nodes are known when creating the graphs:

  • Create a graph containing all possible nodes, and let graphviz lay it out. You may add nodes[pin=true]; at the beginning of the graph (then you won't have to add it later).
  • Layout the graph:

    fdp -Tdot input.gv -o input.pos.gv
    

    You now have a dot file containing all the nodes. You can use this as the base file for all the graphs to be created:

  • For every graph, create a copy of input.pos.gv and hide the unneeded nodes and edges by adding style=invis to their attributes. This makes sure they're not displayed, but also, the place they use in the layout will not be cropped away (for example if at the very top of the graph).
  • Lay them out using something like this (neato and option -n2 being the important parts):

    neato -n2 -Tpng input.pos.v1.gv -o output.v1.png
    

Example:

input.gv:

digraph g{
    node[pin=true];
    a -> b;
    a -> c;
    b -> d;
    b -> e;
    b -> f;
    c -> g;
}

input.pos.modified.gv:

digraph g {
    node [label="\N", pin=true];
    graph [bb="0,0,187,207"];
    a [pos="60.846,70.555", width="0.75", height="0.5", style=invis];
    b [pos="94.351,128.04", width="0.75", height="0.5"];
    c [pos="76.868,18.459", width="0.75", height="0.5"];
    d [pos="119.08,188.8", width="0.75", height="0.5",style=invis];
    e [pos="157.97,106.75", width="0.75", height="0.5"];
    f [pos="27.319,158.05", width="0.75", height="0.5"];
    g [pos="160.1,20.585", width="0.75", height="0.5"];
    a -> b [pos="e,84.434,111.03 70.717,87.493 73.42,92.13 76.411,97.263 79.332,102.27", style=invis];
    a -> c [pos="e,71.34,36.433 66.27,52.918 66.934,50.759 67.624,48.514 68.32,46.252", style=invis];
    b -> d [pos="e,111.86,171.05 101.5,145.62 103.54,150.61 105.8,156.17 108.01,161.59", style=invis];
    b -> e [pos="e,133.72,114.86 118.76,119.87 120.45,119.31 122.17,118.73 123.89,118.16"];
    b -> f [pos="e,49.99,147.9 71.657,138.2 67.726,139.96 63.572,141.82 59.447,143.67"];
    c -> g [pos="e,133.07,19.895 104.12,19.155 110.07,19.307 116.47,19.471 122.74,19.631"];
}

input.png without modifications:

hidden nodes:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!