Search code examples
networkxpygraphviz

Networkx and graphviz. How to suppress node and edge positions in dot output?


Take this simple networkx script.

import networkx as nx

g = nx.DiGraph()
g.add_edge("a","b")
g.add_edge("a","c")
g.add_node("D")

dotter = nx.nx_agraph.to_agraph(g)
dotter.layout("dot")
dot = dotter.to_string()

with open("test_w_pos.dot","w") as fo:
    fo.write(dot)

The output is:

strict digraph "" {
    graph [bb="0,0,162,108"];
    node [label="\N"];
    a    [height=0.5,
        pos="63,90",
        width=0.75];
    b    [height=0.5,
        pos="27,18",
        width=0.75];
    a -> b   [pos="e,35.634,35.269 54.285,72.571 50.04,64.081 44.846,53.693 40.134,44.267"];
    c    [height=0.5,
        pos="99,18",
        width=0.75];
    a -> c   [pos="e,90.366,35.269 71.715,72.571 75.96,64.081 81.154,53.693 85.866,44.267"];
    D    [height=0.5,
        pos="135,90",
        width=0.75];
}

I'd like to not have any of the pos, height and width attributes as they vary from run to run and make it hard to compare to previous runs on complex graphs.

desired output

strict digraph "" {
    node [label="\N"];
    a;
    b;
    a -> b;
    c;
    a -> c;
    D;
}

Both dot files give substantially the same output in svg (see below), so I find the positioning unnecessary and in fact I've never seen this information put into dot files previously.

I could not find anything in to_agraph or dotter.to_string, but I did not notice extra arguments are possible in dotter.layout(dot):

agraph.py

    def layout(self, prog="neato", 👉args=""👈):
        """Assign positions to nodes in graph.

Yes, with this very simplistic file, I could drop the positioning data afterwards. But in a real graph, there will be a lot of other color and label attributes mixed in with the positions.

image with position attributes:

enter image description here

image without position attributes:

enter image description here


Solution

  • If you are only interested in the dot file you can use the pydot interface of networkx and call write_dot, e.g.

    drawing.nx_pydot.write_dot(g, "test.dot")