You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NetworkX节点标签与颜色未按预期显示,求问题排查

问题

我正在编写NetworkX与Neo4j交互的工具包,练习自定义节点/边属性,想模拟Neo4j的显示规则——根据节点的['data']['label']设置节点标签、['data']['color']设置节点颜色,根据边的['label']设置边标签。但运行代码后只有边标签符合预期,节点标签和颜色都不对。打印的标签、颜色字典看起来符合NetworkX文档要求,但绘图结果就是不对,请问哪里出错了?

代码如下:

import networkx as nx
import matplotlib.pyplot as plt

def draw_labeled_net(G: nx.DiGraph):
    plt.figure(figsize = (12,12))
    pos = nx.spring_layout(G)
    nx.draw_networkx_nodes(G, pos, node_color = get_node_colors(G))
    nx.draw_networkx_labels(G, pos, labels = get_node_labels(G), font_size = 12)
    nx.draw_networkx_edges(G, pos, edge_color = 'tab:red')
    nx.draw_networkx_edge_labels(G, pos, edge_labels = get_edge_labels(G))
    plt.show()
                           
def get_node_labels(G: nx.DiGraph):
    labels = {}
    for i in range(len(G.nodes)):
        try:
            labels[i] = G.nodes[i]['data']['label']
        except KeyError as e:
            labels[i] = 'None'
    print()
    print('Node labels:')
    print(labels)
            
def get_edge_labels(G: nx.DiGraph):
    edge_labels = {}
    for edge in list(G.edges):
        try:
            edge_labels[edge] = G.get_edge_data(*edge)['label']
        except KeyError as e:
            edge_labels[edge] = 'None'
            
def get_node_colors(G: nx.DiGraph):
    colors = {}
    for i in range(len(G.nodes)):
        try:
            colors[i] = f"tab:{G.nodes[i]['data']['color']}"
        except KeyError as e:
            colors[i] = 'tab:red'
    print()
    print('Node colors:')
    print(colors)
            

G = nx.DiGraph()
G.add_node(0, data = {'color': 'green', 'label': 'Person'})
G.nodes[0]
G.add_edge(0, 1, label = 'hitBy')

draw_labeled_net(G)

绘图结果:节点显示默认的数字ID(0、1),颜色为默认蓝色,仅边标签hitBy正常显示。

问题分析与解决

核心错误:函数缺少返回值

get_node_labels和get_node_colors函数仅打印了生成的字典,但没有用return语句返回结果。调用这两个函数时,实际传给NetworkX绘图函数的是None,所以绘图时会自动使用默认的节点标签(节点ID)和默认颜色。

次要问题:节点遍历方式不严谨

用range(len(G.nodes))遍历节点,仅在节点ID是连续整数时有效。如果节点ID是非连续整数或字符串,这种遍历方式会直接出错,正确的做法是直接遍历G.nodes获取所有节点ID。

修正后的代码

import networkx as nx
import matplotlib.pyplot as plt

def draw_labeled_net(G: nx.DiGraph):
    plt.figure(figsize=(12, 12))
    pos = nx.spring_layout(G)
    # 获取颜色字典并转为节点顺序对应的列表(避免字典键顺序问题)
    node_color_dict = get_node_colors(G)
    node_color_list = [node_color_dict[node] for node in G.nodes]
    nx.draw_networkx_nodes(G, pos, node_color=node_color_list)
    # 传入返回的标签字典
    nx.draw_networkx_labels(G, pos, labels=get_node_labels(G), font_size=12)
    nx.draw_networkx_edges(G, pos, edge_color='tab:red')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=get_edge_labels(G))
    plt.show()
                           
def get_node_labels(G: nx.DiGraph):
    labels = {}
    # 直接遍历所有节点ID
    for node in G.nodes:
        try:
            labels[node] = G.nodes[node]['data']['label']
        except KeyError:
            labels[node] = 'None'
    print('\nNode labels:')
    print(labels)
    # 添加返回语句
    return labels
            
def get_edge_labels(G: nx.DiGraph):
    edge_labels = {}
    for edge in G.edges:
        try:
            edge_labels[edge] = G.get_edge_data(*edge)['label']
        except KeyError:
            edge_labels[edge] = 'None'
    # 补充返回语句
    return edge_labels
            
def get_node_colors(G: nx.DiGraph):
    colors = {}
    # 直接遍历所有节点ID
    for node in G.nodes:
        try:
            colors[node] = f"tab:{G.nodes[node]['data']['color']}"
        except KeyError:
            colors[node] = 'tab:red'
    print('\nNode colors:')
    print(colors)
    # 添加返回语句
    return colors
            

G = nx.DiGraph()
G.add_node(0, data={'color': 'green', 'label': 'Person'})
G.add_edge(0, 1, label='hitBy')

draw_labeled_net(G)

额外说明

nx.draw_networkx_nodes的node_color参数支持字典,但转为与G.nodes顺序一致的列表更稳妥,可避免字典键顺序不匹配导致的颜色错位问题。

内容的提问来源于stack exchange,提问作者Daniel Frees

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:20:44