【问题标题】:Python: how to color the nodes of a network according to their degree?Python:如何根据度数为网络节点着色?
【发布时间】:2016-06-17 08:58:08
【问题描述】:

我有一个由10000 节点组成的无标度网络,但边缘的纹理和节点的数量使其过于复杂而无法理解。 我希望能够直观地定位连接度最高的节点。

如何根据 k 度为节点着色? 具体来说,我想根据预先分配的范围为它们着色,例如:

  • 如果1<k<10,则为绿色;
  • 淡蓝色如果11<k<20;
  • 蓝色如果21<k<30;
  • 如果31<k<40,则为紫色;
  • ...

这是我获取网络的方法:

import networkx as nx
import matplotlib.pyplot as plt
n = 10000  # Number of nodes
m = 3  # Number of initial links
seed = 500
G = nx.barabasi_albert_graph(n, m, seed)
ncols = 100
pos = {i : (i % ncols, (n-i-1)//ncols) for i in G.nodes()}
fig, ax = plt.subplots()
nx.draw(G, pos, with_labels=False, ax=ax, node_size=10)
degrees=G.degree() #Dict with Node ID, Degree
sum_of_degrees=sum(degrees.values()) #Sum of degrees
avg_degree_unaltered=sum_of_degrees/10000 #The average degree <k>
short_path=nx.average_shortest_path_length(G)
print('seed: '+str(seed)+', short path: '+str(round(short_path,3))+', log(N)=4')
#Plot the graph
plt.xlim(-20,120,10)
plt.xticks(numpy.arange(-20, 130, 20.0))
plt.ylim(120,-20,10) 
plt.yticks(numpy.arange(-20, 130, 20.0))
plt.axis('on')
title_string=('Scale-Free Network') 
subtitle_string=('100x100'+' = '+str(n)+' nodes')
plt.suptitle(title_string, y=0.99, fontsize=17)
plt.title(subtitle_string, fontsize=8)
plt.show()

这是未应用差异着色的结果。 PS: ID 为 0 的初始节点在左上角。

【问题讨论】:

    标签: python matplotlib colors networkx


    【解决方案1】:

    在底层,这只是作为 matplotlib scatter 图实现的,networkx API 允许您传递许多 options through

    import numpy as np
    import matplotlib.colors as mcolors
    import networkx as nx
    import matplotlib.pyplot as plt
    n = 10000  # Number of nodes
    m = 3  # Number of initial links
    seed = 500
    G = nx.barabasi_albert_graph(n, m, seed)
    
    ncols = 100
    pos = {i : (i % ncols, (n-i-1)//ncols) for i in G.nodes()}
    
    fig, ax = plt.subplots()
    degrees = G.degree() #Dict with Node ID, Degree
    nodes = G.nodes()
    n_color = np.asarray([degrees[n] for n in nodes])
    sc = nx.draw_networkx_nodes(G, pos, nodelist=nodes, node_color=n_color, cmap='viridis',
                                with_labels=False, ax=ax, node_size=n_color)
    # use a log-norm, do not see how to pass this through nx API
    # just set it after-the-fact
    sc.set_norm(mcolors.LogNorm())
    fig.colorbar(sc)
    

    这会根据度数缩放颜色和大小。

    这可以使用BoundryNorm 和离散的颜色图来扩展,将节点分割成波段。

    【讨论】:

    • 请检查我编辑的图像。我一直有这个问题。在我的网络中,ID 为“0”的节点位于左上角,而在您的网络中,它位于左下角。这会影响“热图”的显示方式,因为该网络是通过 growthpreferential attachment 从上一行开始生成的。如何在你的情节中改变这一点?
    • 有一个ax.invert_yaxis() 方法可以将0翻转到左上角。放置节点的位置由pos 设置,您可以随意定义。例如,使用{i : (i % ncols, i//ncols for i in G.nodes()} 将最大的节点放在 (0, 0) 附近而不是 (0, 100) 附近。
    • 我喜欢 viridis 配色方案,但我的 matplotlib 1.5 无法识别它。如何包含它?
    【解决方案2】:

    我只会做 3 种颜色:如果 k

    greennodes = [node for node in G.nodes_iter() if G.degree(node)<10]
    bluenodes = [node for node in G.nodes_iter() if 10<=G.degree(node)<20]
    orangenodes = [node for node in G.nodes_iter() if 20<= G.degree(node)]
    
    pos = {i : (i % ncols, (n-i-1)//ncols) for i in G.nodes()}
    fig, ax = plt.subplots()
    nx.draw_networkx_edges(G, pos) #draw edges first
    nx.draw_networkx_nodes(G, pos, with_labels=False, ax=ax, node_size=10, nodelist = 
    greennodes, node_color = 'g') #draw green nodes
    nx.draw_networkx_nodes(G, pos, with_labels=False, ax=ax, node_size=10, nodelist = 
    bluenodes, node_color = 'g') #draw blue nodes
    nx.draw_networkx_nodes(G, pos, with_labels=False, ax=ax, node_size=10, nodelist = 
    orangenodes, node_color = 'g') #draw orange nodes
    

    可能是一种更好的方法(使用 itertools?)以避免必须循环遍历节点 3 次以收集所有节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      相关资源
      最近更新 更多