Python NetworkX 中的图例

8 投票
3 回答
24057 浏览
提问于 2025-04-18 02:13

我有一段代码用来画一个有节点的图,但我在添加合适的图例时遇到了问题:

(抱歉,我无法上传图片,似乎我的信誉不够)

我想要一个包含四种颜色的图例,比如“浅蓝色 = 过时,红色 = 草稿,黄色 = 发布,深蓝色 = 初始化”。

我看到有些解决方案使用了“scatter”,但我觉得那太复杂了。有没有办法用 plt.legend(G.nodes) 来实现呢?

以下是我的代码:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("Obsolete")
G.add_node("Draft")
G.add_node("Release")
G.add_node("Initialisation")
val_map = {'kind1': 2,'kind2': 2,'Obsolete': 2,'Initialisation': 1,'Draft': 4,'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
nodes = nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)

plt.legend(G.nodes())
plt.show() 

3 个回答

1

我尝试了不同的方法,最终找到了一种适合我的情况的解决方案。

下面是我使用的代码:

from matplotlib.lines import Line2D

legend_elements = [
    Line2D([0], [0], marker='o', color='w', label='Label1',markerfacecolor='g', markersize=15),
    Line2D([0], [0], marker='o', color='w', label='label2',markerfacecolor='r', markersize=15),        
]

nx.draw_networkx(G, pos=nx.spring_layout(G),edge_color=(0.8,0.6,0.3), node_color=color)

plt.legend(handles=legend_elements, loc='upper right')
plt.savefig('network_graph.png')
8

看起来你在使用 nx.draw 的时候遇到了一些错误。试试用 nx.draw_networkx 来代替吧。然后在绘制图形的时候,使用一个来自 matplotlib 的坐标轴。这个坐标轴应该包含你节点的标签和颜色,同时在 (0,0) 的位置绘制一个点——这部分比较 tricky。

希望这能帮到你!以下是我运行的代码:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
# For color mapping
import matplotlib.colors as colors
import matplotlib.cm as cmx

G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("Obsolete")
G.add_node("Draft")
G.add_node("Release")
G.add_node("Initialisation")

# You were missing the position.
pos=nx.spring_layout(G)
val_map = {'kind1': 2, 
           'kind2': 2, 
           'Obsolete': 2, 
           'Initialisation': 1, 
           'Draft': 4, 
           'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
# Color mapping
jet = cm = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=max(values))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)

# Using a figure to use it as a parameter when calling nx.draw_networkx
f = plt.figure(1)
ax = f.add_subplot(1,1,1)
for label in val_map:
    ax.plot([0],[0],
            color=scalarMap.to_rgba(val_map[label]),
            label=label)

# Just fixed the color map
nx.draw_networkx(G,pos, cmap=jet, vmin=0, vmax=max(values),
                 node_color=values,
                 with_labels=False, ax=ax)

# Here is were I get an error with your code                                                                                                                         
#nodes = nx.draw(G, cmap=plt.get_cmap('jet'), node_color=values)                                                                             

# Setting it to how it was looking before.                                                                                                              
plt.axis('off')
f.set_facecolor('w')

plt.legend(loc='center')

f.tight_layout()
plt.show()

一些有用的资源:

  1. http://pydoc.net/Python/networkx/1.0.1/networkx.drawing.nx_pylab/
  2. http://matplotlib.org/api/legend_api.html
  3. 使用颜色映射设置 matplotlib 中线条的颜色
  4. http://matplotlib.org/1.3.1/users/artists.html
8

非常感谢你的帮助,不过这并不是我想要的结果。我做了一些修改,这样颜色图例的名称就可以和节点的名称不同了。

这是最终的代码:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
# For color mapping
import matplotlib.colors as colors
import matplotlib.cm as cmx

G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("kind3")
G.add_node("kind4")
G.add_node("kind5")
G.add_node("kind6")

# You were missing the position.
pos=nx.spring_layout(G)
val_map = {'kind1': 2,'kind2': 2,'kind3': 2,'kind4': 1,'kind5':4,'kind6': 3}
#I had this list for the name corresponding t the color but different from the node name
ColorLegend = {'Obsolete': 2,'Initialisation': 1,'Draft': 4,'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
# Color mapping
jet = cm = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=max(values))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)

# Using a figure to use it as a parameter when calling nx.draw_networkx
f = plt.figure(1)
ax = f.add_subplot(1,1,1)
for label in ColorLegend:
    ax.plot([0],[0],color=scalarMap.to_rgba(ColorLegend[label]),label=label)

# Just fixed the color map
nx.draw_networkx(G,pos, cmap = jet, vmin=0, vmax= max(values),node_color=values,with_labels=True,ax=ax)

# Setting it to how it was looking before.                                                                                                              
plt.axis('off')
f.set_facecolor('w')

plt.legend()

f.tight_layout()
plt.show()

撰写回答