如何用DataFrame列数据设置NetworkX节点颜色与大小并绘图?报错排查
NetworkX绘图TypeError错误排查与修复
问题场景
尝试使用NetworkX库,基于DataFrame的Source与Destination列构建边绘制网络图,同时用Circuit列设置节点颜色、Picklist列设置节点大小,运行时触发TypeError错误,报错信息如下:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) ~\AppData\Local\Temp\1\ipykernel_3332\2173665631.py in <module> 45 46 fig = plt.figure() ---> 47 nx.draw_networkx(df, "Source", "Destination", node_color=node_color, node_size=node_size, font_color="whitesmoke") 48 fig.set_facecolor('blue') 49 plt.show() ~\Anaconda3\lib\site-packages\networkx\drawing\nx_pylab.py in draw_networkx(G, pos, arrows, with_labels, **kwds) 301 pos = nx.drawing.spring_layout(G) # default to spring layout 302 ---> 303 draw_networkx_nodes(G, pos, **node_kwds) 304 draw_networkx_edges(G, pos, arrows=arrows, **edge_kwds) 305 if with_labels: ~\Anaconda3\lib\site-packages\networkx\drawing\nx_pylab.py in draw_networkx_nodes(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins) 423 424 try: ---> 425 xy = np.asarray([pos[v] for v in nodelist]) 426 except KeyError as err: 427 raise nx.NetworkXError(f"Node {err} has no position.") from err ~\Anaconda3\lib\site-packages\networkx\drawing\nx_pylab.py in <listcomp>(.0) 423 424 try: ---> 425 xy = np.asarray([pos[v] for v in nodelist]) 426 except KeyError as err: 427 raise nx.NetworkXError(f"Node {err} has no position.") from err TypeError: string indices must be integers
错误原因
- 核心参数错误:
nx.draw_networkx()的第一个参数必须是NetworkX的图对象(如nx.Graph()),你直接传入了DataFrame对象df,导致内部逻辑把字符串当作字典处理,触发"string indices must be integers"错误。 - 图结构未正确构建:没有将DataFrame中的
Source和Destination转换为图的边,图对象未正确初始化。 - 节点属性关联错误:当前
node_color和node_size是对列值去重后的列表,没有与实际节点一一对应,无法正确映射到每个节点。
修复后的代码
import matplotlib.pyplot as plt import pandas as pd import numpy as np import networkx as nx import warnings warnings.filterwarnings('ignore') # 构造测试数据 data = [{'Circuit': 'html','Description':1, 'Duration':10.2, 'Source':'Westchester', 'Destination':'Davie', 'Picklist':1000, 'Postlist':50000.2}, {'Circuit': 'html', 'Description':2, 'Duration':12.1, 'Source':'Westchester', 'Destination':'Davie', 'Picklist':3000, 'Postlist':40000.1}, {'Circuit': 'html', 'Description':3, 'Duration':11.3, 'Source':'Westchester', 'Destination':'Davie', 'Picklist':7000, 'Postlist':50000.2}, {'Circuit': 'html', 'Description':3, 'Duration':8.1, 'Source':'West', 'Destination':'San Bernardino', 'Picklist':3000, 'Postlist':40000.0}, {'Circuit': '.net', 'Description':4, 'Duration':6.2, 'Source':'Queens', 'Destination':'San Bernardino', 'Picklist':5000, 'Postlist':6000.1}, {'Circuit': '.net', 'Description':3, 'Duration':20.1, 'Source':'Queens', 'Destination':'Los Angeles', 'Picklist':5000, 'Postlist':4000.1}, {'Circuit': '.net', 'Description':2, 'Duration':15.5, 'Source':'Brooklyn', 'Destination':'San Francisco', 'Picklist':5000, 'Postlist':9000.3}, {'Circuit': '.net', 'Description':4, 'Duration':7.7, 'Source':'Brooklyn', 'Destination':'Davie', 'Picklist':6000, 'Postlist':10000}, {'Circuit': '.net', 'Description':4, 'Duration':7.7, 'Source':'Los Angeles', 'Destination':'Westchester', 'Picklist':6000, 'Postlist':10000}, {'Circuit': '.net', 'Description':4, 'Duration':7.7, 'Source':'San Berdarnino', 'Destination':'Westchester', 'Picklist':6000, 'Postlist':10000}] df = pd.DataFrame(data) # 1. 从DataFrame构建图结构,Source和Destination作为边的两端 G = nx.from_pandas_edgelist(df, source='Source', target='Destination') # 2. 为节点添加属性:处理同一个节点多条记录的情况,取第一条的Circuit和Picklist值 node_attrs = {} for _, row in df.iterrows(): if row['Source'] not in node_attrs: node_attrs[row['Source']] = {'Circuit': row['Circuit'], 'Picklist': row['Picklist']} if row['Destination'] not in node_attrs: node_attrs[row['Destination']] = {'Circuit': row['Circuit'], 'Picklist': row['Picklist']} # 将属性添加到图的节点中 nx.set_node_attributes(G, node_attrs) # 3. 生成节点颜色和大小列表:与图中的节点顺序一一对应 color_map = {'html': 'red', '.net': 'blue'} node_color = [color_map[G.nodes[node]['Circuit']] for node in G.nodes()] # 缩小Picklist值比例,避免节点过大 node_size = [G.nodes[node]['Picklist'] * 0.1 for node in G.nodes()] # 4. 绘制网络图 fig = plt.figure() pos = nx.spring_layout(G) nx.draw_networkx(G, pos=pos, node_color=node_color, node_size=node_size, font_color="whitesmoke") fig.set_facecolor('blue') plt.show()
关键修复点
- 用
nx.from_pandas_edgelist()正确构建图的边关系 - 给每个节点关联对应的
Circuit和Picklist属性,确保颜色和大小能正确映射到节点 nx.draw_networkx()传入正确的图对象G,并使用布局函数生成节点位置pos
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

