Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualize bipartite network graph created using pandas dataframe

I have data in csv file and i reading it through pandas as below

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

sub_data = pd.read_csv('sample.csv')

Output:

   user_id   item_id    rating

0    772          36     3
1    471         228     5
2    641         401     4
3    312          98     4
4     58         504     5

Creating a Network graph using this data:

 edges = [tuple(x) for x in sub_data[['user_id','item_id']].values.tolist()]
 B = nx.Graph()
 B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
 B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')
 B.add_edges_from(edges, label='rating')    

Plotting the graph using below code:

pos=nx.spring_layout(B)
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True) 

I am getting plot like this: enter image description here

I am only getting nodes. where in i require nodes to be connected and rating as the label to that connection

like image 631
Lalit Jain Avatar asked Sep 13 '25 05:09

Lalit Jain


1 Answers

I tried to run the code you have written, I was able to get a bipartite graph. In your case, I am assuming that NetworkX is able to render a bipartite graph similar to mine, but since your graph has more nodes, the edges are not visible properly. Something like this

Original Graph

You can see that the edges are barely visible. If you also limit the number of nodes to say 10, you might also see the edges. If you are interested in replicating the example, here is the sample csv data (I have added a few more points to the data provided in the question):

,user_id,item_id,rating
0,772,36,3
1,471,228,5
2,641,401,4
3,312,98,4
4,58,504,5
5,67,98,4
6,471,229,3

Now, I understand that you want to see the Graph in Bipartite Layout, with two sets of nodes on either side. You need to use bipartite_layout instead of spring_layout to achieve this.

Here is the full code:

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

sub_data = pd.read_csv('sample.csv')

edges = [tuple(x) for x in sub_data[['user_id','item_id']].values.tolist()]
B = nx.Graph()
B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')
B.add_edges_from(edges, label='rating')

# Now instead of spring_layout, use bipartite_layout

# First specify the nodes you want on left or top
left_or_top = sub_data['user_id'].unique()

# Then create a bipartite layout
pos = nx.bipartite_layout(B, left_or_top)

# Pass that layout to nx.draw
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True)

Bipartite New

Also, note that I have explicitly passed one set of nodes to bipartite_layout instead of using bipartite_sets as mentioned here, because your graph might be disconnected and this would lead to AmbiguousSolution Error. For more information read the documentation here and here.

You can also view the complete code in this Google Colab Notebook.

Update: In case you want to show the edges, you need to assign them like this (Your code for adding the ratings was incorrect)

# Extract the ratings while extracting the edges from DF
edges = [tuple(x) for x in sub_data[['user_id','item_id', 'rating']].values.tolist()]

B = nx.Graph()

B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')

# Now assign the ratings correctly to edges
for row in edges:
    B.add_edge(row[0], row[1], rating=row[2])

Now draw the edge labels using draw_netwokrx_edge_labels:

left_or_top = sub_data['user_id'].unique()
pos = nx.bipartite_layout(B, left_or_top)

# Draw the graph
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True)

# Get the edge labels for ratings
edge_labels = nx.get_edge_attributes(B,'rating')

# Draw the edge labels
nx.draw_networkx_edge_labels(B, pos, edge_labels=edge_labels)

Bipartite with edge labels

References:

  • Bipartite Layout
  • NetworkX - Bipartite Algorithms
  • NetworkX - Bipartite Sets
like image 145
Gambit1614 Avatar answered Sep 15 '25 20:09

Gambit1614