绘制网络图时节点分类颜色显示错误的问题排查
网络图节点着色错误排查
我编写了一段从CSV文件读取邻接矩阵和分类数据来绘制网络图的代码,预期根据节点所属分类为节点着色,但部分节点颜色显示错误。起初以为是使用shell布局导致的问题,但更换其他布局后问题依然存在。假设CSV文件无问题(分类定义正确、矩阵与分类无匹配错误等),请问可能的原因是什么?
代码实现
import pandas as pd import networkx as nx import matplotlib.pyplot as plt def create_network_diagram_from_csv(adjacency_csv_path, categories_csv_path): # 从CSV读取数据到DataFrame df_adjacency = pd.read_csv(adjacency_csv_path, index_col=0) df_categories = pd.read_csv(categories_csv_path, index_col=0) # 转换为NumPy数组方便处理 adjacency_matrix = df_adjacency.to_numpy() # 从DataFrame索引获取节点名称 nodes = df_adjacency.index.to_list() # 创建有向图 G = nx.DiGraph() # 遍历邻接矩阵添加边 for i, source_node in enumerate(nodes): for j, target_node in enumerate(nodes): edge_weight = adjacency_matrix[i, j] if not pd.isna(edge_weight) and edge_weight > 0: G.add_edge(source_node, target_node) # 使用shell布局 pos = nx.shell_layout(G) # 获取每个节点的分类 categories = df_categories.to_dict()['Category'] # 分类到颜色的映射 category_colors = { 'category_a': 'green', 'category_b': 'blue', 'category_c': 'yellow', 'category_d': 'brown', 'category_e': 'red', } # 根据分类获取节点颜色 node_colors = [category_colors.get(categories[node], 'gray') for node in nodes] # 自定义节点大小 node_size = 300 # 绘制网络图 nx.draw(G, pos, with_labels=True, node_size=node_size, node_color=node_colors, font_size=10, arrows=True) # 创建自定义图例 legend_elements = [plt.Line2D([0], [0], marker='o', color='w', label=category, markerfacecolor=color, markersize=10) for category, color in category_colors.items()] # 添加图例 plt.legend(handles=legend_elements, title='Categories', loc='upper right', frameon=True) # 重新绘制边(指定颜色) edge_color = 'grey' nx.draw_networkx_edges(G, pos, arrows=True, edge_color=edge_color) plt.show() adjacency_csv_path = r'C:\location of file' categories_csv_path = r'C:\location of file' create_network_diagram_from_csv(adjacency_csv_path, categories_csv_path)
测试数据
分类数据
Node, Category node_1, category_a node_2, category_b node_3, category_d node_4, category_a node_5, category_a
邻接矩阵数据
,node_1,node_2,node_3,node_4,node_5 node_1, 1, 0, 0, 0, 1 node_2, 0, 0, 1, 0, 0 node_3, 0, 1, 0, 1, 1 node_4, 0, 1, 0, 1, 0 node_5, 1, 1, 1, 1, 1
可能的原因及解决办法
- 节点顺序不匹配:
nx.draw()默认按照NetworkX图对象内部的节点顺序(即G.nodes()返回的顺序)绘制节点,但你生成node_colors时用的是邻接矩阵的nodes列表顺序。如果这两个顺序不一致,颜色就会对应错误。
解决方法:生成颜色列表时改用图对象的节点顺序:node_colors = [category_colors.get(categories[node], 'gray') for node in G.nodes()] - 节点名称存在隐形差异:虽然你确认CSV没问题,但仍需检查
categories字典的键与G.nodes()中的节点名是否完全一致(比如是否存在空格、大小写差异或特殊字符)。可以添加打印语句排查:print("图中节点:", list(G.nodes())) print("分类字典中的节点:", list(categories.keys())) - 重复绘制导致的视觉混淆:你先调用
nx.draw()绘制了包含边的网络图,之后又调用nx.draw_networkx_edges()重新绘制边。虽然这不会直接影响节点颜色,但如果边的颜色覆盖了节点边缘,可能造成视觉上的颜色误解。可以去掉重复的边绘制代码,或者在nx.draw()中直接指定edge_color参数:nx.draw(G, pos, with_labels=True, node_size=node_size, node_color=node_colors, font_size=10, arrows=True, edge_color='grey') - NetworkX版本兼容问题:部分旧版本的NetworkX在处理颜色列表与节点顺序的对应关系上存在bug,建议升级到最新稳定版(比如3.x系列)。
内容的提问来源于stack exchange,提问作者Alonzo
相关产品推荐
相关产品推荐

