0

I am working on an example Erdos Renyi graph with class objects associated with nodes How to use user-defined class object as a networkx node? in Networkx. First, an empty graph is created. Then I create 4 nodes and associate data (class object) to it. This allows me to have access to the attributes of the class object by doing this G.node[0]['data'].x

as explained in How to use user-defined class object as a networkx node?.

The class object code is taken from: https://pythonprogramming.net/many-blob-objects-intermediate-python-tutorial/

The code looks like this:

import pygame
import random
import networkx
from matplotlib import pyplot as plt
from scipy.stats import bernoulli

STARTING_BLUE_BLOBS = 10
STARTING_RED_BLOBS = 3

WIDTH = 800
HEIGHT = 600
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)

def Erdos_Renyi_gr(Bglob,p):
    Gcons = nx.Graph()
    #add nodes
    for i in range(4):
        Gcons.add_node(i, data = Bglob[i])

    for node1 in Gcons.nodes():
        for node2 in Gcons.nodes():
            if node1 < node2 and bernoulli.rvs(p=p):
                Gcons.add_edge(node1,node2)

    return Gcons

class Blob:

    def __init__(self, color):
        self.x = random.randrange(0, WIDTH)
        self.y = random.randrange(0, HEIGHT)
        self.size = random.randrange(4,8)
        self.color = color


def main():
   blue_blobs = dict(enumerate([Blob(BLUE) for i in 
    range(STARTING_BLUE_BLOBS)]))
    red_blobs = dict(enumerate([Blob(RED) for i in 
    range(STARTING_RED_BLOBS)])) 
    Gb = Erdos_Renyi_gr(blue_blobs,0.5)
    nx.write_gexf(Gb, 'quaker_network.gexf')

    nx.draw(Gb, with_labels=True)
    plt.draw()
    plt.show()
if __name__ == '__main__':
    main() `  

The problem is that none of the "write" commands that stores the Networkx graph in a format to be opened with Gephi works for this graph. I guess the error is mainly due to the data associated with my nodes as the error says:

KeyError: <class '__main__.Blob'>

The full error stack trace looks something like this:

runfile('G:/Bolbclassy.py')
Traceback (most recent call last):

  File "<ipython-input-2-03d6a2a74cde>", line 1, in <module>
  runfile('G:/Bolbclassy.py', )

  File "C:Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", 
 line 705, in runfile
    execfile(filename, namespace)

  File "C:Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", 
line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "G:/Bolbclassy.py", line 55, in <module>
    main()

  File "G:/Bolbclassy.py", line 49, in main
    nx.write_gexf(Gb, 'quaker_network.gexf')

  File "<decorator-gen-571>", line 2, in write_gexf

  File "C:Anaconda3\lib\site-packages\networkx\utils\decorators.py", line 
227, in _open_file
    result = func_to_be_decorated(*new_args, **kwargs)

  File "C:Anaconda3\lib\site-packages\networkx\readwrite\gexf.py", line 88, 
in write_gexf
    writer.add_graph(G)

  File "C:Anaconda3\lib\site-packages\networkx\readwrite\gexf.py", line 305, 
in add_graph
self.add_nodes(G, graph_element)

  File "C:Anaconda3\lib\site-packages\networkx\readwrite\gexf.py", line 340, 
in add_nodes
    node_data, default)

  File "C:Anaconda3\lib\site-packages\networkx\readwrite\gexf.py", line 436, 
in add_attributes
    attr_id = self.get_attr_id(make_str(k), self.xml_type[val_type],

KeyError: <class '__main__.Blob'>

Any ideas how this can be fixed?

Thanks,

user710
  • 161
  • 2
  • 12
  • Please provide the full error stack trace. It is unclear, what command(s) exactly caused the error, and where it was raised. – Paul Brodersen Feb 12 '19 at 10:12
  • 1
    Also, while a class instance is hashable and hence can be used as a networkx node object, there is no way to write an export function that knows what to do with arbitrary python objects. In other words, you will have to define the `write` behaviour yourself. – Paul Brodersen Feb 12 '19 at 10:14
  • Thank you very much. Yes, I understand your point. So, I should use ` G.add_node(i, color='sth',x='sth',y='sth')` to add all the attributes of each node one by one to it, right? – user710 Feb 12 '19 at 16:15
  • 1
    The last line in our stack trace suggests that that might work. It seems to convert the data to strings and look up the XML type that goes with it. Just try it out. If it doesn't, report back if you can't figure out what is going wrong. – Paul Brodersen Feb 13 '19 at 10:17

0 Answers0