How to convert networkx graphs to graph-tool

This small function converts a networkx graph to a graph-tool compatible graph, preserving both the edge properties and node properties.

def networkx_to_graph_tool(networkx_graph: nx.Graph) -> gt.Graph:
    """
    Converts a networkx graph to a graph-tool graph.
    """
    # Phase 0: Create a directed or undirected graph-tool Graph
    graph_tool_graph = gt.Graph(directed=networkx_graph.is_directed())

    # Add the Graph properties as "internal properties"
    for key, value in list(networkx_graph.graph.items()):
        # Convert the value and key into a type for graph-tool
        tname, value, key = get_prop_type(value, key)

        prop = graph_tool_graph.new_graph_property(tname)  # Create the PropertyMap

        graph_tool_graph.graph_properties[key] = prop  # Set the PropertyMap
        graph_tool_graph.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 networkx_graph.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 = graph_tool_graph.new_vertex_property(tname)  # Create the PropertyMap
            graph_tool_graph.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!
    graph_tool_graph.vertex_properties['id'] = graph_tool_graph.new_vertex_property('string')
    # Add the edge properties second
    eprops = set()  # cache keys to only add properties once
    for src, dst, data in networkx_graph.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 = graph_tool_graph.new_edge_property(tname)  # Create the PropertyMap
            graph_tool_graph.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 networkx_graph.nodes(data=True):
        # Create the vertex and annotate for our edges later
        v = graph_tool_graph.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()):
            graph_tool_graph.vp[key][v] = value  # vp is short for vertex_properties
    # Add the edges
    for src, dst, data in networkx_graph.edges(data=True):
        # Look up the vertex structs from our vertices mapping and add edge.
        e = graph_tool_graph.add_edge(vertices[src], vertices[dst])
        # Add the edge properties
        for key, value in list(data.items()):
            graph_tool_graph.ep[key][e] = value  # ep is short for edge_properties
    # Done, finally!
    return graph_tool_graph    }

Further reading

Read more in the tech topic.

Let's talk!

I'm Carlo Nicolini — I am interested on the reliability of AI reasoning systems (interpretability, inference-time methods, probabilistic language programming) and on quantitative portfolio optimization (I am a maintainer of skfolio). If you're working on something in these areas and think we might collaborate, chat, discuss, I'm happy to talk about it!

The best way to reach me is on via DM on LinkedIn.