python-3.xnetworkxcytoscapepyvis

Pyvis problem with Networkx after Graph Reload


I'm here because I ran into some strange behavior during my work with graphs.

I placed here a simple python script to show the problem:

pip install networkx pyvis
from pyvis.network import Network
import networkx as nx
import json

# Generate Graph
nx_graph = nx.cycle_graph(10)
nx_graph.nodes[1]['title'] = 'Number 1'
nx_graph.nodes[1]['group'] = 1
nx_graph.nodes[3]['title'] = 'I belong to a different group!'
nx_graph.nodes[3]['group'] = 10
nx_graph.add_node(20, size=20, title='couple', group="Coppia")
nx_graph.add_node(21, size=15, title='couple', group="Coppia")
nx_graph.add_edge(20, 21, weight=5)
nx_graph.add_node("Rome 112", title='Home Street', weight=5)
nx_graph.add_node(25, size=25, label='lonely', title='lonely node', group=3)
# Save NetworkX Graph as cytoscape format
cyJson = nx.cytoscape_data(nx_graph)
with open("nx.cyjs", 'w') as outfile:
    json.dump(cyJson, outfile, indent=4)

# Visualize graph
nt1 = Network('500px', '500px', select_menu=True, filter_menu=True)
nt1.from_nx(nx_graph) # populates the nodes and edges data structures
# nt.show_buttons(filter_=['nodes', 'edges', 'physics'])
nt1.show('nx-before.html', False) # Display Graph

# After some time... in another day

# Reload Graph from cytoscape format
reloadGraph = nx.DiGraph()
with open("nx.cyjs", 'r') as readfile:
    reloadGraph = nx.cytoscape_graph(json.load(readfile))
# Print 
nt2 = Network('500px', '500px', select_menu=True, filter_menu=True)
nt2.from_nx(reloadGraph)
nt2.show('nx-after.html', False)

In other words, I would have a graph generated after a lot of work that I would like to save and reload on occasion, normally first by working it and then showing a cut of it graphically.

Unfortunately this doesn't happen and I get this error:

Traceback (most recent call last):
  File "C:\Users\A409806\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\223.8617.48\plugins\python\helpers\pydev\pydevd.py", line 1496, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Users\A409806\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\223.8617.48\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:\Users\A409806\Documents\01_gitRepo\controlflowgraph4cmr\Demo\GraphDemo\graphDemo2.py", line 31, in <module>
    nt2.from_nx(reloadGraph)
  File "C:\Users\A409806\AppData\Local\Programs\Python\Python310\lib\site-packages\pyvis\network.py", line 717, in from_nx
    self.add_edge(e[0], e[1], **e[2])
TypeError: Network.add_edge() got multiple values for argument 'source'
python-BaseException

The expected outcome would be that a new html file would be created showing the same graph.

Thanks in advance for all your help!


Solution

  • Not sure if this is the reason, but the chosen format seems to cause problems after reloading for Pyvis.

    Trying with another standard format: node_link_data, node_link_graph the problem disappeared and it is possible to recreate the graph identical to the original.

    This is the Succes code:

    from pyvis.network import Network
    import networkx as nx
    import json
    
    # Generate Graph
    nx_graph = nx.cycle_graph(10)
    nx_graph.nodes[1]['title'] = 'Number 1'
    nx_graph.nodes[1]['group'] = 1
    nx_graph.nodes[3]['title'] = 'I belong to a different group!'
    nx_graph.nodes[3]['group'] = 10
    nx_graph.add_node(20, size=20, title='couple', group="Coppia")
    nx_graph.add_node(21, size=15, title='couple', group="Coppia")
    nx_graph.add_edge(20, 21, weight=5)
    nx_graph.add_node("Rome 112", title='Home Street', weight=5)
    nx_graph.add_node(25, size=25, label='lonely', title='lonely node', group=3)
    # Save NetworkX Graph as cytoscape format
    cyJson = nx.node_link_data(nx_graph) # <---- Change here
    with open("nx.json", 'w') as outfile:
        json.dump(cyJson, outfile, indent=4)
    
    # Visualize graph
    nt1 = Network('500px', '500px', select_menu=True, filter_menu=True)
    nt1.from_nx(nx_graph) # populates the nodes and edges data structures
    # nt.show_buttons(filter_=['nodes', 'edges', 'physics'])
    nt1.show('nx-before.html', False) # Display Graph
    
    # Now Reload Graph cytoscape format
    reloadGraph = nx.DiGraph()
    with open("nx.json", 'r') as readfile:
        reloadGraph = nx.node_link_graph(json.load(readfile)) # <---- Change here
    # Print
    nt2 = Network('500px', '500px', select_menu=True, filter_menu=True)
    nt2.from_nx(reloadGraph)
    nt2.show('nx-after.html', False)
    

    if anyone else has other ideas, feel free to contribute