Getting layout coordinates of graph vertices using python, networkx, pygraphviz

Viewed 1209

I want to create a graph using NetworkX, layout the graph using Graphviz(via pygraphviz). I have successfully ran all the examples in the NetworkX pygraphviz examples documentation

The question I have is - how do I get the coordinates (x, y) and dimensions (width, height) of the vertices back into the NetworkX graph. That is the goal. I want only Graphviz' layout capabilities, not drawing capabilities. Is that possible using this stack (NetworkX, pygraphviz, graphviz)? Any other way?

The background motivation is this. Graphviz outputs png, or ps, or svg and many other formats. But I don't want to be constrained by the formats Graphviz handles. And I want to be able to post-process the layout results, even if I end up outputting the popular formats like Graphviz does support.

Update: I have rewritten the question for clarity. The advice on Graphviz output formats miss the point. It is the layout data that I need

Update2: One suggestion was to make Graphviz ouptput in some format that I can then parse the layout data back from. The suggestion was for SVG. I had had considered that possibility. Graphviz outputs json (according to Graphviz output formats documentation page). I failed to make it work on my windows installation - for some reason not all the output formats were present). However it is the approach that makes me uneasy. Parsing formatted output for data that was used to create that output seems backwards. The data itself should have been made available, I think.

Update 3 - There is a similar question - How to get the coordinates from layout from graphviz?. One of the answers suggests using NetworkX. However the answer uses layout made by NetworkX and not Graphviz. The author of the answer did not know how to get the Graphviz layout data. So my question remains relevant, and yet to be answered

Update 4 - it is 07-2019 and I still did not find a way to solve this. I marked one answer as accepted - but with a caveat - I still am in the dark despite the good advice found in that answer

4 Answers

regarding Update 4

it is still 2019 but this works perfectly for my needs

import networkx as nx
G = nx.complete_graph(10)
pos = nx.drawing.nx_agraph.graphviz_layout(G, prog='dot')
print(pos)

give me

{0: (327.0, 666.0), 1: (504.0, 594.0), 2: (327.0, 522.0), 3: (449.0, 450.0), 4: (283.0, 378.0), 5: (283.0, 306.0), 6: (473.0, 234.0), 7: (287.0, 162.0), 8: (418.0, 90.0), 9: (287.0, 18.0)}

a dict of nodes and positions!

Greets dom

Here is another solution. It differs from Dominik Kummer's as it exposes the pygraphviz.AGraph object, making it possible to specify arbitrary gaphviz attributes to customize the layout.

import networkx as nx
import pygraphviz as pgv

g = nx.complete_graph(10)
ag = nx.drawing.nx_agraph.to_agraph(g)
ag.layout(prog='dot')
layout = [ag.get_node(n).attr['pos'] for n in ag.nodes()]
layout = [[int(ss) for ss in s.split(",")] for s in layout]
print(layout)

give me:

[[327, 666], [504, 594], [327, 522], [449, 450], [283, 378], [283, 306], [473, 234], [287, 162], [418, 90], [287, 18]]

Related