Python – How to create a directed network diagram from a Pandas adjacency matrix dataframe?

How to create a directed network diagram from a Pandas adjacency matrix dataframe?… here is a solution to the problem.

How to create a directed network diagram from a Pandas adjacency matrix dataframe?

I have the following form of pandas data frame, df,

    A    B    C    D
A   0   0.5   0.5  0 
B   1    0    0    0
C   0.8  0    0   0.2
D   0    0    1    0

I’m trying to create a networkx diagram from it. I tried the following code variation:

a)

G=networkx.from_pandas_adjacency(df)
G=networkx. DiGraph(G) 

B)

G=networkx.from_pandas_adjacency(df, create_using=networkx. DiGraph())

However, what happens in the end is the graphical object:

(for option A) basically takes only one value of the two parallel edges between any two given nodes and removes the other value.

(for option B) takes one of the two parallel edges between any two given nodes as the value of both edges.

For example,

print( list ( filter ( lambda x: x[0]=='A' and x[1] == 'B', list(G.edges.data()) ) ) )

and

print( list ( filter ( lambda x: x[0]=='B' and x[1] == 'A', list(G.edges.data()) ) ) )

Print 1 and [] for option A.
Print two 1s for option B.

How do I fix this?

Solution

Try numpy as a workaround.

G = nx.from_numpy_matrix(df.values, parallel_edges=True, 
                         create_using=nx. MultiDiGraph())

# Because we use numpy, labels need to be reset
label_mapping = {0: "A", 1: "B", 2: "C", 3: "D"}
G = nx.relabel_nodes(G, label_mapping)

G.edges(data=True)

OutMultiEdgeDataView([('A', 'B', {'weight': 0.5}), 
                      ('A', 'C', {'weight': 0.5}), 
                      ('B', 'A', {'weight': 1.0}), 
                      ('C', 'A', {'weight': 0.8}), 
                      ('C', 'D', {'weight': 0.2}), 
                      ('D', 'C', {'weight': 1.0})])

In a more general case, to get a label_mapping, you can use

label_mapping = {idx: val for idx, val in enumerate(df.columns)}

This seems to be a bug in NetworkX 2.0. They will fix it in 2.1. See this issue for more information.

Related Problems and Solutions