【问题标题】:Plotting the degree distribution of a graph using nx.degree_histogram使用 nx.degree_histogram 绘制图的度数分布
【发布时间】:2019-05-26 06:56:18
【问题描述】:

我尝试使用以下代码绘制networkx.DiGraphG的度数分布:

def plot_degree_In(G):
    in_degrees = G.in_degree()
    in_degrees=dict(in_degrees)
    in_values = sorted(set(in_degrees.values()))
    in_hist = [list(in_degrees.values()).count(x) for x in in_values]

    plt.figure() 
    plt.grid(False)
    plt.loglog(in_values, in_hist, 'r.') 
    #plt.loglog(out_values, out_hist, 'b.') 
    #plt.legend(['In-degree', 'Out-degree'])
    plt.xlabel('k')
    plt.ylabel('p(k)')
    plt.title('Degree Distribution')
    plt.xlim([0, 2*100**1])

但后来我意识到这不是正确的做法,所以我将其更改为:

def plot_degree_dist(G):
    degree_hist = nx.degree_histogram(G) 
    degree_hist = np.array(degree_hist, dtype=float)
    degree_prob = degree_hist/G.number_of_nodes()
    plt.loglog(np.arange(degree_prob.shape[0]),degree_prob,'b.')
    plt.xlabel('k')
    plt.ylabel('p(k)')
    plt.title('Degree Distribution')
    plt.show()

但这给了我一个没有数据的空图。

【问题讨论】:

    标签: python matplotlib histogram networkx directed-graph


    【解决方案1】:

    今天遇到了同样的问题。一些典型的度数分布图 (examples) 不会对度数进行分类。相反,他们分散在对数图上每个度数的计数。

    这就是我想出的。由于在常见的直方图函数中似乎很难关闭分箱,我决定选择标准的Counter 来完成这项工作。

    degrees 预计可以在节点度上进行一些迭代(由 networkx 返回)。

    Counter.items() 给出了对 [(degree, count)] 的列表。将列表解压缩到 x 和 y 后,我们可以准备带有对数刻度的轴,并发布散点图。

    from collections import Counter
    from operator import itemgetter
    import matplotlib.pyplot as plt
    
    # G = some networkx graph
    
    degrees = G.in_degree()
    degree_counts = Counter(degrees)                                                                                                 
    x, y = zip(*degree_counts.items())                                                      
                                                                                                     
    plt.figure(1)   
                                                                                                                                                                                                                                                          
    # prep axes                                                                                                                      
    plt.xlabel('degree')                                                                                                             
    plt.xscale('log')                                                                                                                
    plt.xlim(1, max(x))  
                                                                                                               
    plt.ylabel('frequency')                                                                                                          
    plt.yscale('log')                                                                                                                
    plt.ylim(1, max(y))                                                                                                             
                                                                                                                                         # do plot                                                                                                                        
    plt.scatter(x, y, marker='.')                                                                                                    
    plt.show()
    

    我手动剪裁了 xlimylim,因为自动缩放会使点在对数刻度中丢失一点。小点标记效果最好。

    希望对你有帮助

    编辑:这篇文章的早期版本包括对度数对进行排序,当然,对于具有明确定义的 x 和 y 的散点图来说,这不是必需的。查看示例图片:

    【讨论】:

      【解决方案2】:

      我们可以使用nx.degree_histogram,它返回网络中度数的频率列表,其中度数是列表中对应的索引。但是,此功能仅适用于无向图。我将首先说明如何在无向图的情况下使用它,然后展示一个有向图的示例,我们可以通过稍微调整nx.degree_histogram来了解如何获得度数分布。

      • 对于无向图

      对于有向图,我们可以使用nx.degree_histogram。 Bellow 是一个使用随机图生成器nx.barabasi_albert_graph 的示例。

      通常,在绘制度数分布时,xy 轴都取对数,这有助于查看网络 x 是否为 scale-free(度数分布遵循幂律的网络),因此我们可以使用 matplotlib 的 plt.loglog

      m=3
      G = nx.barabasi_albert_graph(1000, m)
      
      degree_freq = nx.degree_histogram(G)
      degrees = range(len(degree_freq))
      plt.figure(figsize=(12, 8)) 
      plt.loglog(degrees[m:], degree_freq[m:],'go-') 
      plt.xlabel('Degree')
      plt.ylabel('Frequency')
      


      • 对于有向图

      对于有向图,我们可以稍微修改函数nx.degree_histogram 来考虑入度和出度:

      def degree_histogram_directed(G, in_degree=False, out_degree=False):
          """Return a list of the frequency of each degree value.
      
          Parameters
          ----------
          G : Networkx graph
             A graph
          in_degree : bool
          out_degree : bool
      
          Returns
          -------
          hist : list
             A list of frequencies of degrees.
             The degree values are the index in the list.
      
          Notes
          -----
          Note: the bins are width one, hence len(list) can be large
          (Order(number_of_edges))
          """
          nodes = G.nodes()
          if in_degree:
              in_degree = dict(G.in_degree())
              degseq=[in_degree.get(k,0) for k in nodes]
          elif out_degree:
              out_degree = dict(G.out_degree())
              degseq=[out_degree.get(k,0) for k in nodes]
          else:
              degseq=[v for k, v in G.degree()]
          dmax=max(degseq)+1
          freq= [ 0 for d in range(dmax) ]
          for d in degseq:
              freq[d] += 1
          return freq
      

      与上面类似,我们可以为入度或/和出度生成图表。下面是一个带有随机比例-绿色图的示例:

      G = nx.scale_free_graph(5000)
      
      in_degree_freq = degree_histogram_directed(G, in_degree=True)
      out_degree_freq = degree_histogram_directed(G, out_degree=True)
      degrees = range(len(in_degree_freq))
      plt.figure(figsize=(12, 8)) 
      plt.loglog(range(len(in_degree_freq)), in_degree_freq, 'go-', label='in-degree') 
      plt.loglog(range(len(out_degree_freq)), out_degree_freq, 'bo-', label='out-degree')
      plt.xlabel('Degree')
      plt.ylabel('Frequency')
      

      【讨论】:

        【解决方案3】:

        使用测试代码打印(进出)度直方图的一种方法:

        import matplotlib.pyplot as plt
        import networkx as nx
        
        def plot_degree_dist(G):
            degrees = [G.degree(n) for n in G.nodes()]
            plt.hist(degrees)
            plt.show()
        
        plot_degree_dist(nx.gnp_random_graph(100, 0.5, directed=True))
        

        可以通过向plt.hist 添加第二个参数来调整直方图的 bin 数量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-05
          • 2013-09-14
          • 1970-01-01
          • 2021-07-24
          • 1970-01-01
          • 2022-10-30
          • 2013-01-06
          • 2021-04-10
          相关资源
          最近更新 更多