Search code examples
pythonpandasgraphnetworkxweighted-graph

Create a weighted graph based on Dataframe


consider a data frame like this:

id source Target Weight
1 A B 1
2 A C 2
3 A D 3
4 A E 4

I want to depict a graph with networkX which shows us two things: 1-Node with more connections has a larger size, respectively. 2-Edge with more weight has a thicker line in between. enter image description here


Solution

  • We can set the edge_attr to Weight when we create the Graph from_pandas_edgelist then when we draw the graph we can get_edge_attributes and pass that as the width of whatever drawing operation.

    For node_size we can use nx.degree to get the Degree from the Graph:

    nx.degree(G)
    
    [('A', 4), ('B', 1), ('C', 1), ('D', 1), ('E', 1)]
    

    We can then scale up the degree by some factor since these values are going to be quite small. I've chosen a factor of 200 here, but this can be adjusted:

    [d[1] * 200 for d in nx.degree(G)]
    
    [800, 200, 200, 200, 200]
    

    All together it can look like:

    G = nx.from_pandas_edgelist(
        df,
        source='source',
        target='Target',
        edge_attr='Weight'  # Set Edge Attribute to Weight Column
    )
    
    # Get Degree values and scale
    scaled_degree = [d[1] * 200 for d in nx.degree(G)]
    nx.draw(G,
            # Weights Based on Column
            width=list(nx.get_edge_attributes(G, 'Weight').values()),
            # Node size based on degree
            node_size=scaled_degree,
            # Colour Based on Degree
            node_color=scaled_degree,
            # Set color map to determine colours
            cmap='rainbow',
            with_labels=True)
    
    plt.show()
    

    weighted and coloured graph on degree


    Setup Used:

    import networkx as nx
    import pandas as pd
    from matplotlib import pyplot as plt
    
    df = pd.DataFrame({
        'id': [1, 2, 3, 4],
        'source': ['A', 'A', 'A', 'A'],
        'Target': ['B', 'C', 'D', 'E'],
        'Weight': [1, 2, 3, 4]
    })