pythonnetworkxgraphvizpygraphvizgraph-layout

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


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


Solution

  • Michael, I re-read your question and comments and with the tools I know that work (and I know how to use), this is what I'd do in your shoes. I would draw your charts in DOT/GraphViz and then choose a human-readable and easy-to-parse format such as SVG, "plain", or even x-dot. Why? Not to get the graph itself -- some of these don't even realize graphs -- but because these formats are human-readable and contain the X-Y coordinates of the different drawing components. You can use those coordinates and sizes to your own purposes. Some snips from a simple graph I just did should illustrate. SVG first

    <svg width="89pt" height="188pt"
    
    <g id="node1" class="node"><title>A</title>
    <ellipse fill="none" stroke="black" cx="54" cy="-162" rx="27" ry="18"/>
    <text text-anchor="middle" x="54" y="-158.3" font-family="Times New Roman,serif" font-size="14.00">A</text>
    

    Or in "plain" format, perhaps simplest for parsing:

    graph 1 0.75 1.5
    node A 0.375 1.25 0.75 0.5 A solid ellipse black lightgrey
    node B 0.375 0.25 0.75 0.5 B solid ellipse black lightgrey
    edge A B 4 0.375 0.99579 0.375 0.88865 0.375 0.7599 0.375 0.64045 solid black
    stop
    

    Or VML which is html-like:

    <v:oval style="position:absolute; left: 0.00; top: 0.00; width: 54.00; height: 36.00" filled="false"  >
    

    Etc... Not hard to imagine parsing out all the X-Ys of the various elements and repurposing them as you see fit.