Import graph from graphml restoring node positions with NetworkX
Asked Answered
T

1

0

I'm saving a graph with node positions in graphml format.

I want to load it and draw its nodes in the same positions as before. Data saved in the graphml file consists of primitive types, whereas data used by mathplotlib to draw the graph is a dictionary {string: array([x, y]), dtype=float32}, where the array is most probably a numpy array.

I'm using NetworkX 1.9.1, and this is my code. I guess the problem may be due messy iteration. Plus, I can't build from scratch the structure used to draw positions.

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

#load the graph from the graphml file
def load_graph(file_path):
    G = nx.read_graphml(file_path)
    return G

def show_graph(G):
    #used to create the structure, computation useless
    pos = nx.circular_layout(G)

    print(pos)

    #try to refill the structure (don't produce expected results)
    for (node, node_pos) in pos.items():
        node_pos[0] = G.node[node]['x']
        node_pos[1] = G.node[node]['y']

    #draw the graph
    print(pos)
    plt.clf()
    nx.draw_networkx(G, pos)
    plt.show()

file_path = 'netw_a.graphml'
A = load_graph(file_path)
show_graph(A)

Here is a test file for import

<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
  <key attr.name="x" attr.type="double" for="node" id="d2" />
  <key attr.name="y" attr.type="double" for="node" id="d1" />
  <key attr.name="name" attr.type="string" for="graph" id="d0" />
  <graph edgedefault="undirected">
    <data key="d0">path_graph(4)</data>
    <node id="0">
      <data key="d1">0.394087123189</data>
      <data key="d2">0.0</data>
    </node>
    <node id="1">
      <data key="d1">0.743297296307</data>
      <data key="d2">0.402465740641</data>
    </node>
    <node id="2">
      <data key="d1">0.529781867707</data>
      <data key="d2">0.942892202945</data>
    </node>
    <node id="3">
      <data key="d1">0.0</data>
      <data key="d2">1.0</data>
    </node>
    <edge source="0" target="1" />
    <edge source="1" target="2" />
    <edge source="2" target="3" />
  </graph>
</graphml>
Terbia answered 9/3, 2015 at 22:1 Comment(0)
C
2

Assign the x and y values to the a dictionary with node keys

In [1]: pos = {}

In [2]: for n,data in G.node.items():
   ...:     pos[n] = (data['x'],data['y'])
   ...:  
Cartie answered 10/3, 2015 at 0:42 Comment(2)
This solution adopts simple lists instead of NumPy arrays. It works, though, so I guess it's fine. Any comments before I accept your answer?Terbia
If you want numpy arrays (and there is no real reason to here) you can just write numpy.array(data['x'],data['y']).Cartie

© 2022 - 2024 — McMap. All rights reserved.