基于节点值,在networkx中为节点绘制不同的颜色

49

我有一个包含节点和有向边的大型图形。此外,我还有一个额外的列表,其中为每个节点分配了值。

现在,我想根据它们的节点值更改每个节点的颜色。例如,将具有非常高值的节点绘制为红色,将具有低值的节点绘制为蓝色(类似于热力图)。这是否容易实现?如果不能使用networkx,则我也可以使用Python中的其他库。

2个回答

79
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap=plt.get_cmap('viridis'), node_color=values, with_labels=True, font_color='white')
plt.show()

产生的结果为 enter image description here


values 中的数字与 G.nodes() 中的节点相关联。 也就是说,values 中的第一个数字与 G.nodes() 中的第一个节点相关联,第二个数字与第二个节点相关联,以此类推。


注意:import numpy as np 没有被使用。 - Heath Raftery

11

对于一般情况,我们有一个值列表来指示节点的某个属性,并且我们想为给定的节点分配一种颜色,以便表达该属性的 规模(例如从红到蓝),以下是一种方法:

import matplotlib as mpl
from matplotlib import pyplot as plt
from pylab import rcParams
import networkx as nx

G = nx.Graph()
G.add_edges_from([('A', 'D'), ('Z', 'D'), ('F', 'J'), ('A', 'E'), ('E', 'J'),('Z', 'K'), ('B', 'A'), ('B', 'D'), ('A', 'J'), ('Z', 'F'),('Z', 'D'), ('A', 'B'), ('J', 'D'), ('J', 'E'), ('Z', 'J'),('K', 'J'), ('B', 'F'), ('B', 'J'), ('A', 'Z'), ('Z', 'E'),('C', 'Z'), ('C', 'A')])

假设我们有以下字典将每个节点映射到给定的值:

color_lookup = {k:v for v, k in enumerate(sorted(set(G.nodes())))}
# {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'J': 6, 'K': 7, 'Z': 8}

我们可以使用mpl.colors.Normalize来规范化color_lookup中的值,使它们基于节点取值的最小值和最大值处于[0,1]范围内,然后使用matplotlib.cm.ScalarMappable将规范化的值映射到颜色映射中的颜色。在这里,我将使用mpl.cm.coolwarm

low, *_, high = sorted(color_lookup.values())
norm = mpl.colors.Normalize(vmin=low, vmax=high, clip=True)
mapper = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.coolwarm)

rcParams['figure.figsize'] = 12, 7
nx.draw(G, 
        nodelist=color_lookup,
        node_size=1000,
        node_color=[mapper.to_rgba(i) 
                    for i in color_lookup.values()], 
        with_labels=True)
plt.show()

enter image description here

如果需要另一种颜色地图,则只需更改mpl.cm.ScalarMappable中的cmap参数:

mapper = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.summer)
nx.draw(G, 
        nodelist=color_lookup,
        node_size=1000,
        node_color=[mapper.to_rgba(i) 
                    for i in color_lookup.values()], 
        with_labels=True)
plt.show()

我们将得到:

enter image description here

同样地,我们可以根据节点的degree设置节点的颜色,通过定义一个将所有节点映射到它们对应度数的字典,并采取与上述步骤相同的步骤:

d = dict(G.degree)
# {'A': 6, 'D': 4, 'Z': 7, 'F': 3, 'J': 7, 'E': 3, 'K': 2, 'B': 4, 'C': 2}
low, *_, high = sorted(d.values())
norm = mpl.colors.Normalize(vmin=low, vmax=high, clip=True)
mapper = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.coolwarm)

nx.draw(G, 
        nodelist=d,
        node_size=1000,
        node_color=[mapper.to_rgba(i) 
                    for i in d.values()], 
        with_labels=True,
        font_color='white')
plt.show()

输入图像描述


3
好的:low,* _,high = sorted(d.values()) - Oren
如何根据节点所属社区对其进行着色? - Ash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接