Python NetworkX -- 根据属性选项的数量自动设置节点颜色

Python NetworkX -- set node color automatically based on number of attribute options

我正在使用 NetworkX 来分析和可视化社交网络。通常,网络中的节点具有与其关联的属性信息,例如划分。但是,我并不总是知道属性划分可能有多少选项。例如,有时网络中可能只有 3 个分区表示为节点属性,其他时候可能有 30 个分区。

我已经弄清楚如何根据节点属性设置节点颜色(参见下面的代码)。然而,在这个例子中,我知道节点属性组有多少不同的选项(5 个选项),并自动设置每种颜色。

当节点属性只有3或5个选项时,选择节点属性颜色并不难,但是当还有更多选项时,这将变得不现实。

我想弄清楚的是如何根据提供的节点属性选项的数量自动选择最佳节点属性颜色。

有时我有 5 个选项用于属性着色,有时我可能有 30 个选项用于节点属性着色,我不想单独设置每个节点颜色.

我不确定这是否是我应该能够使用 colormap 函数完成的事情,或者这是否仅适用于通过度中心性等数字度量的颜色节点。

NETWORKX 代码

import networkx as nx

pylab inline

# create an empty graph
g = nx.Graph()

# open csv edgelist and read edges into graph
for line in open('phils_network_edgelist.csv', 'rb'):
    edge = line.rstrip().split(',')
    g.add_edge(edge[0], edge[1])

# draw network without node color
nx.draw(g, with_labels=False, node_size=25)

# read in node attributes as list of tuples
group_attr = []
for line in open('phils_network_attribute_group.csv', 'rb'):
    group_attr.append(tuple(line.rstrip().split(',')))

# convert list of tuples into a dict
group_attr_dict = dict(set(sorted(group_attr)))

# set nodes attributes
nx.set_node_attributes(g, "group", group_attr_dict)

# create empty list for node colors
node_color = []

# for each node in the graph
for node in g.nodes(data=True):

    # if the node has the attribute group1
    if 'group1' in node[1]['group']:
        node_color.append('blue')

    # if the node has the attribute group1
    elif 'group2' in node[1]['group']:
        node_color.append('red')

    # if the node has the attribute group1
    elif 'group3' in node[1]['group']:
        node_color.append('green')

    # if the node has the attribute group1
    elif 'group4' in node[1]['group']:
        node_color.append('yellow')

    # if the node has the attribute group1
    elif 'group5' in node[1]['group']:
        node_color.append('orange')  

# draw graph with node attribute color
nx.draw(g, with_labels=False, node_size=25, node_color=node_color)

网络数据

In[58]: 

g.nodes(data=True)

Out[58]:

[('BD', {'group': 'group5'}),
 ('WC', {'group': 'group3'}),
 ('BA', {'group': 'group4'}),
 ('WM', {'group': 'group3'}),
 ('JR', {'group': 'group1'}),
 ('JS', {'group': 'group3'}),
 ('JL', {'group': 'group4'}),
 ('JM', {'group': 'group2'}),
 ('JK', {'group': 'group2'}),
 ('JF', {'group': 'group2'}),
 ('JG', {'group': 'group2'}),
 ('JA', {'group': 'group2'}),
 ('JB', {'group': 'group4'}),
 ('JC', {'group': 'group4'}),
 ('RR', {'group': 'group3'}),
 ('RS', {'group': 'group3'}),
 ('TTI', {'group': 'group3'}),
 ('RB', {'group': 'group1'}),
 ('RL', {'group': 'group3'}),
 ('RO', {'group': 'group4'}),
 ('LHA', {'group': 'group2'}),
 ('LHI', {'group': 'group1'}),
 ('GF', {'group': 'group2'}),
 ('GB', {'group': 'group4'}),
 ('EM', {'group': 'group2'}),
 ('HR', {'group': 'group5'}),
 ('BS', {'group': 'group3'}),
 ('HH', {'group': 'group4'}),
 ('HA', {'group': 'group1'}),
 ('PS', {'group': 'group1'}),
 ('PW', {'group': 'group1'}),
 ('PB', {'group': 'group1'}),
 ('PC', {'group': 'group5'}),
 ('MFR', {'group': 'group4'}),
 ('JMA', {'group': 'group5'}),
 ('PN', {'group': 'group4'}),
 ('PL', {'group': 'group3'}),
 ('ZL', {'group': 'group4'}),
 ('EB', {'group': 'group2'}),
 ('ET', {'group': 'group3'}),
 ('EW', {'group': 'group1'}),
 ('ER', {'group': 'group3'}),
 ('MF', {'group': 'group3'}),
 ('MA', {'group': 'group4'}),
 ('MM', {'group': 'group2'}),
 ('MN', {'group': 'group4'}),
 ('MH', {'group': 'group3'}),
 ('MK', {'group': 'group2'}),
 ('JLA', {'group': 'group2'}),
 ('MP', {'group': 'group1'}),
 ('MS', {'group': 'group4'}),
 ('MR', {'group': 'group4'}),
 ('FI', {'group': 'group5'}),
 ('CJ', {'group': 'group4'}),
 ('CO', {'group': 'group5'}),
 ('CM', {'group': 'group4'}),
 ('CB', {'group': 'group2'}),
 ('CG', {'group': 'group2'}),
 ('CF', {'group': 'group5'}),
 ('CD', {'group': 'group3'}),
 ('CS', {'group': 'group2'}),
 ('CP', {'group': 'group2'}),
 ('CV', {'group': 'group2'}),
 ('KC', {'group': 'group1'}),
 ('KB', {'group': 'group3'}),
 ('SY', {'group': 'group2'}),
 ('KF', {'group': 'group2'}),
 ('KD', {'group': 'group3'}),
 ('KH', {'group': 'group1'}),
 ('SW', {'group': 'group1'}),
 ('KL', {'group': 'group2'}),
 ('KP', {'group': 'group3'}),
 ('KW', {'group': 'group1'}),
 ('SM', {'group': 'group2'}),
 ('SB', {'group': 'group4'}),
 ('DJ', {'group': 'group2'}),
 ('DD', {'group': 'group2'}),
 ('DV', {'group': 'group5'}),
 ('BJ', {'group': 'group3'}),
 ('DR', {'group': 'group2'}),
 ('KWI', {'group': 'group4'}),
 ('TW', {'group': 'group2'}),
 ('TT', {'group': 'group2'}),
 ('LH', {'group': 'group3'}),
 ('LW', {'group': 'group3'}),
 ('TM', {'group': 'group3'}),
 ('LS', {'group': 'group3'}),
 ('LP', {'group': 'group2'}),
 ('TG', {'group': 'group3'}),
 ('JCU', {'group': 'group2'}),
 ('AL', {'group': 'group1'}),
 ('AP', {'group': 'group3'}),
 ('AS', {'group': 'group3'}),
 ('IM', {'group': 'group4'}),
 ('AW', {'group': 'group3'}),
 ('HHI', {'group': 'group1'})]

In [59]:

g.edges(data=True)

Out[59]:

[('BD', 'ZL', {}),
 ('BD', 'JCU', {}),
 ('BD', 'DJ', {}),
 ('BD', 'BA', {}),
 ('BD', 'CB', {}),
 ('BD', 'CG', {}),
 ('BD', 'AS', {}),
 ('BD', 'MH', {}),
 ('BD', 'AP', {}),
 ('BD', 'HH', {}),
 ('BD', 'TM', {}),
 ('BD', 'CF', {}),
 ('BD', 'CP', {}),
 ('BD', 'DR', {}),
 ('BD', 'CV', {}),
 ('BD', 'EB', {}),
 ('WC', 'JCU', {}),
 ('WC', 'JS', {}),
 ('BA', 'JR', {}),
 ('BA', 'JB', {}),
 ('BA', 'RR', {}),
 ('BA', 'RS', {}),
 ('BA', 'LH', {}),
 ('BA', 'PC', {}),
 ('BA', 'TTI', {}),
 ('BA', 'PL', {}),
 ('BA', 'JCU', {}),
 ('BA', 'CF', {}),
 ('BA', 'EB', {}),
 ('BA', 'GF', {}),
 ('BA', 'AS', {}),
 ('BA', 'IM', {}),
 ('BA', 'BJ', {}),
 ('BA', 'CS', {}),
 ('BA', 'KH', {}),
 ('BA', 'SW', {}),
 ('BA', 'MH', {}),
 ('BA', 'MR', {}),
 ('BA', 'HHI', {}),
 ('WM', 'EM', {}),
 ('WM', 'JCU', {}),
 ('WM', 'CO', {}),
 ('WM', 'LP', {}),
 ('WM', 'AW', {}),
 ('WM', 'KD', {}),
 ('WM', 'TT', {}),
 ('WM', 'JS', {}),
 ('WM', 'PB', {}),
 ('WM', 'JM', {}),
 ('WM', 'MFR', {}),
 ('WM', 'RB', {}),
 ('WM', 'MR', {}),
 ('WM', 'DV', {}),
 ('WM', 'TG', {}),
 ('WM', 'JF', {}),
 ('WM', 'JMA', {}),
 ('WM', 'FI', {}),
 ('WM', 'JB', {}),
 ('JR', 'GF', {}),
 ('JR', 'MFR', {}),
 ('JR', 'KH', {}),
 ('JR', 'JB', {}),
 ('JS', 'EM', {}),
 ('JS', 'PS', {}),
 ('JS', 'MF', {}),
 ('JS', 'JCU', {}),
 ('JS', 'KD', {}),
 ('JS', 'MH', {}),
 ('JS', 'TTI', {}),
 ('JS', 'RB', {}),
 ('JS', 'TG', {}),
 ('JL', 'KB', {}),
 ('JL', 'MN', {}),
 ('JL', 'LW', {}),
 ('JL', 'CS', {}),
 ('JL', 'ET', {}),
 ('JL', 'ER', {}),
 ('JM', 'EM', {}),
 ('JM', 'PS', {}),
 ('JM', 'KD', {}),
 ('JM', 'CD', {}),
 ('JM', 'JK', {}),
 ('JM', 'TG', {}),
 ('JM', 'RO', {}),
 ('JM', 'CV', {}),
 ('JK', 'HR', {}),
 ('JK', 'PS', {}),
 ('JF', 'EM', {}),
 ('JF', 'PS', {}),
 ('JF', 'LP', {}),
 ('JF', 'LHA', {}),
 ('JF', 'CD', {}),
 ('JF', 'RB', {}),
 ('JF', 'JG', {}),
 ('JF', 'KF', {}),
 ('JG', 'CJ', {}),
 ('JG', 'SY', {}),
 ('JG', 'KF', {}),
 ('JG', 'LHA', {}),
 ('JG', 'CD', {}),
 ('JG', 'RB', {}),
 ('JG', 'BS', {}),
 ('JA', 'CS', {}),
 ('JB', 'KC', {}),
 ('JB', 'JCU', {}),
 ('JB', 'MA', {}),
 ('JB', 'AW', {}),
 ('JB', 'KWI', {}),
 ('JB', 'KH', {}),
 ('JB', 'CF', {}),
 ('JB', 'EB', {}),
 ('JB', 'PB', {}),
 ('JB', 'MFR', {}),
 ('JB', 'KW', {}),
 ('JB', 'RB', {}),
 ('JB', 'MR', {}),
 ('JB', 'RL', {}),
 ('JB', 'FI', {}),
 ('JB', 'JMA', {}),
 ('JC', 'SM', {}),
 ('RR', 'MS', {}),
 ('RR', 'SW', {}),
 ('RR', 'LH', {}),
 ('RS', 'LH', {}),
 ('TTI', 'JCU', {}),
 ('TTI', 'SW', {}),
 ('TTI', 'CF', {}),
 ('RB', 'EM', {}),
 ('RB', 'PS', {}),
 ('RB', 'SY', {}),
 ('RB', 'JCU', {}),
 ('RB', 'KD', {}),
 ('RB', 'CF', {}),
 ('RB', 'LHI', {}),
 ('RB', 'CD', {}),
 ('RB', 'MH', {}),
 ('RB', 'CJ', {}),
 ('RB', 'TG', {}),
 ('RB', 'EB', {}),
 ('RO', 'PS', {}),
 ('LHA', 'CJ', {}),
 ('LHA', 'SY', {}),
 ('LHA', 'KF', {}),
 ('LHA', 'CD', {}),
 ('LHI', 'PS', {}),
 ('LHI', 'CJ', {}),
 ('GF', 'KC', {}),
 ('GF', 'MA', {}),
 ('GB', 'HR', {}),
 ('GB', 'MM', {}),
 ('GB', 'LS', {}),
 ('EM', 'LP', {}),
 ('EM', 'DV', {}),
 ('EM', 'TG', {}),
 ('HR', 'MM', {}),
 ('HR', 'MH', {}),
 ('HR', 'EB', {}),
 ('HR', 'LS', {}),
 ('BS', 'CD', {}),
 ('HH', 'ZL', {}),
 ('HH', 'CB', {}),
 ('HH', 'CP', {}),
 ('HH', 'DR', {}),
 ('HH', 'CV', {}),
 ('HA', 'SM', {}),
 ('PS', 'KD', {}),
 ('PS', 'CF', {}),
 ('PS', 'TG', {}),
 ('PW', 'CM', {}),
 ('PW', 'TW', {}),
 ('PW', 'TT', {}),
 ('PW', 'MH', {}),
 ('PW', 'AL', {}),
 ('PW', 'MP', {}),
 ('PW', 'CS', {}),
 ('PW', 'HHI', {}),
 ('PW', 'EW', {}),
 ('PB', 'CO', {}),
 ('PB', 'KH', {}),
 ('PB', 'CF', {}),
 ('PB', 'MFR', {}),
 ('PB', 'AW', {}),
 ('PB', 'MA', {}),
 ('PC', 'CS', {}),
 ('PC', 'JCU', {}),
 ('PC', 'SW', {}),
 ('MFR', 'KC', {}),
 ('MFR', 'JCU', {}),
 ('MFR', 'KH', {}),
 ('MFR', 'MH', {}),
 ('MFR', 'MR', {}),
 ('JMA', 'KWI', {}),
 ('JMA', 'AW', {}),
 ('PN', 'SB', {}),
 ('PL', 'HHI', {}),
 ('PL', 'MK', {}),
 ('PL', 'LH', {}),
 ('ZL', 'CB', {}),
 ('ZL', 'AP', {}),
 ('ZL', 'CP', {}),
 ('ZL', 'DR', {}),
 ('ZL', 'CV', {}),
 ('EB', 'JCU', {}),
 ('EB', 'DJ', {}),
 ('EB', 'CM', {}),
 ('EB', 'SW', {}),
 ('EB', 'MM', {}),
 ('EB', 'LS', {}),
 ('EB', 'CS', {}),
 ('EB', 'CP', {}),
 ('EB', 'CV', {}),
 ('ET', 'LW', {}),
 ('ET', 'ER', {}),
 ('ET', 'KB', {}),
 ('EW', 'TW', {}),
 ('EW', 'TT', {}),
 ('EW', 'HHI', {}),
 ('EW', 'AL', {}),
 ('ER', 'LW', {}),
 ('ER', 'KB', {}),
 ('MA', 'KW', {}),
 ('MA', 'AW', {}),
 ('MA', 'MR', {}),
 ('MM', 'LS', {}),
 ('MH', 'JCU', {}),
 ('MH', 'SY', {}),
 ('MH', 'DJ', {}),
 ('MH', 'CM', {}),
 ('MH', 'AL', {}),
 ('MH', 'SW', {}),
 ('MH', 'CF', {}),
 ('MH', 'LS', {}),
 ('MH', 'CS', {}),
 ('MH', 'TG', {}),
 ('MH', 'CP', {}),
 ('MH', 'CV', {}),
 ('MK', 'LH', {}),
 ('MK', 'KL', {}),
 ('MK', 'JLA', {}),
 ('MK', 'MS', {}),
 ('MK', 'CS', {}),
 ('JLA', 'CM', {}),
 ('JLA', 'KL', {}),
 ('JLA', 'MS', {}),
 ('JLA', 'CS', {}),
 ('JLA', 'SB', {}),
 ('JLA', 'HHI', {}),
 ('MP', 'TW', {}),
 ('MP', 'TT', {}),
 ('MP', 'HHI', {}),
 ('MS', 'CS', {}),
 ('MS', 'HHI', {}),
 ('FI', 'KW', {}),
 ('FI', 'AW', {}),
 ('FI', 'CF', {}),
 ('CJ', 'SY', {}),
 ('CJ', 'DD', {}),
 ('CJ', 'CD', {}),
 ('CO', 'AW', {}),
 ('CM', 'TW', {}),
 ('CM', 'TT', {}),
 ('CM', 'AL', {}),
 ('CM', 'CS', {}),
 ('CB', 'DJ', {}),
 ('CB', 'CP', {}),
 ('CB', 'CV', {}),
 ('CG', 'CF', {}),
 ('CF', 'JCU', {}),
 ('CF', 'AW', {}),
 ('CF', 'KH', {}),
 ('CF', 'LH', {}),
 ('CF', 'AP', {}),
 ('CF', 'AS', {}),
 ('CF', 'KW', {}),
 ('CF', 'CS', {}),
 ('CF', 'CV', {}),
 ('CD', 'SY', {}),
 ('CD', 'LP', {}),
 ('CD', 'KF', {}),
 ('CS', 'JCU', {}),
 ('CS', 'TW', {}),
 ('CS', 'TT', {}),
 ('CS', 'AS', {}),
 ('CS', 'LH', {}),
 ('CS', 'SB', {}),
 ('CS', 'HHI', {}),
 ('CP', 'DJ', {}),
 ('CP', 'AP', {}),
 ('CP', 'DR', {}),
 ('CP', 'CV', {}),
 ('CV', 'DJ', {}),
 ('CV', 'AP', {}),
 ('CV', 'DR', {}),
 ('KB', 'LW', {}),
 ('SY', 'KF', {}),
 ('KF', 'AP', {}),
 ('KD', 'TG', {}),
 ('SW', 'BJ', {}),
 ('SW', 'IM', {}),
 ('SW', 'LH', {}),
 ('KL', 'TT', {}),
 ('KP', 'TM', {}),
 ('KW', 'JCU', {}),
 ('SB', 'AL', {}),
 ('DJ', 'TG', {}),
 ('BJ', 'IM', {}),
 ('KWI', 'AW', {}),
 ('TW', 'TT', {}),
 ('TW', 'AL', {}),
 ('TW', 'HHI', {}),
 ('TT', 'AL', {}),
 ('TT', 'HHI', {}),
 ('LH', 'JCU', {}),
 ('JCU', 'AP', {}),
 ('JCU', 'AS', {}),
 ('AL', 'HHI', {})]

这是一个如何使用颜色图的示例。这有点棘手。如果你想要一个自定义的离散颜色图,你可以试试这个 SO answer Matplotlib discrete colorbar

import matplotlib.pyplot as plt
# create number for each group to allow use of colormap
from itertools import count
# get unique groups
groups = set(nx.get_node_attributes(g,'group').values())
mapping = dict(zip(sorted(groups),count()))
nodes = g.nodes()
colors = [mapping[g.node[n]['group']] for n in nodes]

# drawing nodes and edges separately so we can capture collection for colobar
pos = nx.spring_layout(g)
ec = nx.draw_networkx_edges(g, pos, alpha=0.2)
nc = nx.draw_networkx_nodes(g, pos, nodelist=nodes, node_color=colors, 
                            with_labels=False, node_size=100, cmap=plt.cm.jet)
plt.colorbar(nc)
plt.axis('off')
plt.show()