How to work with multipartite graphs in NetworkX or igraph?

2.1k views Asked by At

I'm working with mutipartite networks, specifically in this case with a quadripartite one. First of all, in NetworkX it seems that only is possible to work with complete multipartite networks trough nx.complete_multipartite_graph(), and not with more general multipartite ones (correct me if I'm wrong please). I can start to looking at igraph or another Python package if necessary.

Inspired in James A. Foster's question, I create a draw of a network similar to mine, in a smaller scale of course and with some of its features. I use this code only to see it graphically and as help to explain what I want to do.

I used the following nomenclature: 1st and 2nd columns form the "X bipartite network", 2nd and 3rd columns form the "Y bipartite network", 3rd and 4th columns form the "Z bipartite network", and I have all of this networks in separate files. I would like to integrate them in just one multipartite network as this draw:

Quadripartite graph

(1) How should I proceed with this? As I understand, I can't use the nx.compose() function.

One problem I find, at least in this code for drawing it, is due to the fact that in my real network the 1st and 4th column have the same elements! So, if I use the same names in both columns, the NetworkX interpretation is not useful to me and that's why I use different numbers in the 4th column.

(2) What should I do? I need to specify that both columns are somehow different in spite of having the same elements.

An important information is this graph is "temporary ordered", i.e., the interactions occurs chronologically from left to right, therefore self-loops between the 1st and 4th column are forbidden, and this columns are of particular interest to me.

(3) How can I extract the network between the 1st and 4th column? In this small network for example, node 6 is connected with 11 and 14, and node 11 with 1, 2 and 6 of course.

import networkx as nx
import matplotlib.pyplot as plt

def position_QuadriPartiteGraph(Graph, Parts):
uPos = {}
vPos = {}
for index1, agentType in enumerate(Parts):
    uPos[agentType] = index1

QG = nx.Graph()
QG.add_nodes_from([1,2,3,4,5,6,7], agentType='alfa')
QG.add_nodes_from(['a','b','c'], agentType='beta')
QG.add_nodes_from(['A','B','C','D','E','F'], agentType='gamma')
QG.add_nodes_from([8,9,10,11,12,13,14], agentType='delta')

myEdges = [(1,'a'), # beginning of bipartite network X
           (1,'b'), # X
           (2,'b'), # X
           (3,'a'), # X
           (4,'a'), # X
           (5,'a'), # X
           (6,'c'), # X
           (7,'a'), # end of bipartite network X
           ('a','A'), # beginning of bipartite network Y
           ('a','B'), # Y
           ('a','E'), # Y
           ('b','B'), # Y
           ('b','C'), # Y
           ('b','D'), # Y
           ('c','F'), # end of bipartite network Y
           ('A',8), # beginning of bipartite network Z
           ('A',9), # Z
           ('B',9), # Z
           ('B',13), # Z
           ('C',10), # Z
           ('C',11), # Z
           ('C',12), # Z
           ('D',12), # Z
           ('E',13), # Z
           ('F', 11), # Z
           ('F', 14)] # end of bipartite network Z

[QG.add_edge(u, v) for u, v in myEdges]

nx.draw(QG, pos=position_QuadriPartiteGraph(QG, ['alfa', 'beta', 'gamma', 'delta']), with_labels=True)
plt.savefig("multipartite_graph.png")
plt.show()

Many thanks for your help in advance,

Jorge

1

There are 1 answers

1
DYZ On BEST ANSWER

My first suggestion is to keep the three networks separately as g1, g2, and g3. Also, make g3 labels different from g1 labels by, say, making them negative (this solves problem (2)). Then you can solve your problem (3) by progressively looking at the neighbors of g1 agents in g2, g2 agents in g3, etc.:

edges14 = sum([sum([[(i,y) for y in g3.neighbors(x)] 
              for x in sum([g2.neighbors(x) for x in g1.neighbors(i) if x in g2],
                           []) if x in g3],
                    []) for i in g1],
               [])
set(edges14)
# {(5, -9), (4, -8), (5, -13), (2, -12), (1, -11), (5, -8), (6, -14), 
#  (4, -9), (2, -9), (4, -13), (2, -13), (1, -10), (3, -13), (6, -11), 
#  (1, -13), (2, -10), (3, -9), (1, -9), (7, -9), (1, -12), (7, -13), 
#  (2, -11), (3, -8), (1, -8), (7, -8)}