Skip to content

Instantly share code, notes, and snippets.

@tomshaffner
Forked from bbengfort/nx2gt.py
Created June 3, 2019 15:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tomshaffner/7a2df7f9ec6b1be33dd0413897125683 to your computer and use it in GitHub Desktop.
Save tomshaffner/7a2df7f9ec6b1be33dd0413897125683 to your computer and use it in GitHub Desktop.
Convert a networkx to graph-tool graph
# -*- coding: utf-8 -*-
import networkx as nx
import graph_tool as gt
def get_prop_type(value, key=None):
"""
Performs typing and value conversion for the graph_tool PropertyMap class.
If a key is provided, it also ensures the key is in a format that can be
used with the PropertyMap. Returns a tuple, (type name, value, key)
"""
if isinstance(key, str):
# Encode the key as utf-8
key = key.encode('utf-8', errors='replace')
# Deal with the value
if isinstance(value, bool):
tname = 'bool'
elif isinstance(value, int):
tname = 'float'
value = float(value)
elif isinstance(value, float):
tname = 'float'
elif isinstance(value, str):
tname = 'string'
value = value.encode('utf-8', errors='replace')
elif isinstance(value, dict):
tname = 'object'
else:
tname = 'string'
value = str(value)
#If key is a byte value, decode it to string
try:
key = key.decode('utf-8')
except AttributeError:
pass
return tname, value, key
def nx2gt(nxG):
"""
Converts a networkx graph to a graph-tool graph.
"""
# Phase 0: Create a directed or undirected graph-tool Graph
gtG = gt.Graph(directed=nxG.is_directed())
# Add the Graph properties as "internal properties"
for key, value in list(nxG.graph.items()):
# Convert the value and key into a type for graph-tool
tname, value, key = get_prop_type(value, key)
prop = gtG.new_graph_property(tname) # Create the PropertyMap
gtG.graph_properties[key] = prop # Set the PropertyMap
gtG.graph_properties[key] = value # Set the actual value
# Phase 1: Add the vertex and edge property maps
# Go through all nodes and edges and add seen properties
# Add the node properties first
nprops = set() # cache keys to only add properties once
for node, data in nxG.nodes(data=True):
# Go through all the properties if not seen and add them.
for key, val in list(data.items()):
if key in nprops: continue # Skip properties already added
# Convert the value and key into a type for graph-tool
tname, _, key = get_prop_type(val, key)
prop = gtG.new_vertex_property(tname) # Create the PropertyMap
gtG.vertex_properties[key] = prop # Set the PropertyMap
# Add the key to the already seen properties
nprops.add(key)
# Also add the node id: in NetworkX a node can be any hashable type, but
# in graph-tool node are defined as indices. So we capture any strings
# in a special PropertyMap called 'id' -- modify as needed!
gtG.vertex_properties['id'] = gtG.new_vertex_property('string')
# Add the edge properties second
eprops = set() # cache keys to only add properties once
for src, dst, data in nxG.edges(data=True):
# Go through all the edge properties if not seen and add them.
for key, val in list(data.items()):
if key in eprops: continue # Skip properties already added
# Convert the value and key into a type for graph-tool
tname, _, key = get_prop_type(val, key)
prop = gtG.new_edge_property(tname) # Create the PropertyMap
gtG.edge_properties[key] = prop # Set the PropertyMap
# Add the key to the already seen properties
eprops.add(key)
# Phase 2: Actually add all the nodes and vertices with their properties
# Add the nodes
vertices = {} # vertex mapping for tracking edges later
for node, data in nxG.nodes(data=True):
# Create the vertex and annotate for our edges later
v = gtG.add_vertex()
vertices[node] = v
# Set the vertex properties, not forgetting the id property
data['id'] = str(node)
for key, value in list(data.items()):
gtG.vp[key][v] = value # vp is short for vertex_properties
# Add the edges
for src, dst, data in nxG.edges(data=True):
# Look up the vertex structs from our vertices mapping and add edge.
e = gtG.add_edge(vertices[src], vertices[dst])
# Add the edge properties
for key, value in list(data.items()):
gtG.ep[key][e] = value # ep is short for edge_properties
# Done, finally!
return gtG
if __name__ == '__main__':
# Create the networkx graph
nxG = nx.Graph(name="Undirected Graph")
nxG.add_node("v1", name="alpha", color="red")
nxG.add_node("v2", name="bravo", color="blue")
nxG.add_node("v3", name="charlie", color="blue")
nxG.add_node("v4", name="hub", color="purple")
nxG.add_node("v5", name="delta", color="red")
nxG.add_node("v6", name="echo", color="red")
nxG.add_edge("v1", "v2", weight=0.5, label="follows")
nxG.add_edge("v1", "v3", weight=0.25, label="follows")
nxG.add_edge("v2", "v4", weight=0.05, label="follows")
nxG.add_edge("v3", "v4", weight=0.35, label="follows")
nxG.add_edge("v5", "v4", weight=0.65, label="follows")
nxG.add_edge("v6", "v4", weight=0.53, label="follows")
nxG.add_edge("v5", "v6", weight=0.21, label="follows")
for item in nxG.edges(data=True):
print(item)
# Convert to graph-tool graph
gtG = nx2gt(nxG)
gtG.list_properties()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment