【问题标题】:Plot bipartite graph using networkx in Python [duplicate]在Python中使用networkx绘制二分图[重复]
【发布时间】:2014-07-18 15:49:26
【问题描述】:

我有一个二分图的 n1×n2 双邻接矩阵 A。矩阵 A 是一个 scipy.sparse csc 矩阵。我想在networkx中使用A来绘制二分图。假设节点根据其名为 node_class 的类标签着色。我可以做到以下几点:

import networkx as nx
G = nx.from_numpy_matrix(A)
graph_pos = nx.fruchterman_reingold_layout(G)
degree = nx.degree(G)
nx.draw(G, node_color = node_class, with_labels = False, node_size = [v * 35 for v in degree.values()])

上面的代码适用于正方形密集邻接矩阵。但是对于非方形双邻接矩阵 A 则不然。错误是:

'Adjacency matrix is not square.'

此外,我拥有的矩阵 A 是一个 scipy.sparse 矩阵,因为它非常大并且有很多零。因此,我想通过堆叠 A 并添加零来避免创建 (n1+n2)-by-(n1+n2) 邻接矩阵。

我查看了 NetworkX 的二分图文档,它没有提到如何使用双邻接矩阵绘制双分图,或使用双邻接稀疏矩阵创建图。如果有人能告诉我如何绘制二分图,那就太好了!

【问题讨论】:

    标签: python matrix graph networkx


    【解决方案1】:

    我不相信有一个 NetworkX 函数可以从邻接矩阵创建图形,因此您必须自己编写。 (不过,他们确实有 bipartite module 你应该看看。)

    这是定义函数的一种方法,该函数采用稀疏的双向邻接矩阵并将其转换为 NetworkX 图(请参阅 cmets 进行解释)。

    # Input: M scipy.sparse.csc_matrix
    # Output: NetworkX Graph
    def nx_graph_from_biadjacency_matrix(M):
        # Give names to the nodes in the two node sets
        U = [ "u{}".format(i) for i in range(M.shape[0]) ]
        V = [ "v{}".format(i) for i in range(M.shape[1]) ]
    
        # Create the graph and add each set of nodes
        G = nx.Graph()
        G.add_nodes_from(U, bipartite=0)
        G.add_nodes_from(V, bipartite=1)
    
        # Find the non-zero indices in the biadjacency matrix to connect 
        # those nodes
        G.add_edges_from([ (U[i], V[j]) for i, j in zip(*M.nonzero()) ])
    
        return G
    

    请参阅下面的示例用例,其中我使用nx.complete_bipartite_graph 生成完整的图表:

    import networkx as nx, numpy as np
    from networkx.algorithms import bipartite
    from scipy.sparse import csc_matrix
    import matplotlib.pyplot as plt
    RB = nx.complete_bipartite_graph(3, 2)
    A  = csc_matrix(bipartite.biadjacency_matrix(RB, row_order=bipartite.sets(RB)[0]))
    G = nx_graph_from_biadjacency_matrix(A)
    nx.draw_circular(G, node_color = "red", with_labels = True)
    plt.show()
    

    这是输出图:

    【讨论】:

      【解决方案2】:

      这是一个简单的例子:

      import networkx as nx
      import matplotlib.pyplot as plt
      from networkx.algorithms import matching
      %matplotlib inline
      
      ls=[
      [0,0,0,1,1],
      [1,0,0,0,0],
      [1,0,1,0,0],
      [0,1,1,0,0],
      [1,0,0,0,0]
      ]
      g = nx.Graph()
      a=['a'+str(i) for i in range(len(ls))]
      b=['b'+str(j) for j in range(len(ls[0]))]
      g.add_nodes_from(a,bipartite=0)
      g.add_nodes_from(b,bipartite=1)
      
      for i in range(len(ls)):
          for j in range(len(ls[i])):
              if ls[i][j] != 0:
                  g.add_edge(a[i], b[j])
      pos_a={}
      x=0.100
      const=0.100
      y=1.0
      for i in range(len(a)):
          pos_a[a[i]]=[x,y-i*const]
      
      xb=0.500
      pos_b={}
      for i in range(len(b)):
          pos_b[b[i]]=[xb,y-i*const]
      
      nx.draw_networkx_nodes(g,pos_a,nodelist=a,node_color='r',node_size=300,alpha=0.8)
      nx.draw_networkx_nodes(g,pos_b,nodelist=b,node_color='b',node_size=300,alpha=0.8)
      
      # edges
      pos={}
      pos.update(pos_a)
      pos.update(pos_b)
      #nx.draw_networkx_edges(g,pos,edgelist=nx.edges(g),width=1,alpha=0.8,edge_color='g')
      nx.draw_networkx_labels(g,pos,font_size=10,font_family='sans-serif')
      m=matching.maximal_matching(g)
      nx.draw_networkx_edges(g,pos,edgelist=m,width=1,alpha=0.8,edge_color='k')
      
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2017-11-25
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 2017-07-06
        • 2021-07-27
        • 2021-06-03
        • 2011-11-21
        相关资源
        最近更新 更多