使用NetworkX和Matplotlib绘制数据关系图的问题求助
我来帮你搞定NetworkX绘图的这几个问题!咱们一步步解决节点/边颜色区分、图片保存为空和空窗口弹出的问题:
一、给不同节点集设置专属颜色
NetworkX的add_nodes_from并不支持直接设置node_color(这个参数是绘图函数专用的,不是添加节点时用的)。正确做法是先添加所有节点,再给不同集合的节点分配对应颜色,最后在绘制节点时传入颜色列表:
# 假设你的三个节点集合已经定义:entities, sornodes, consumernodes G = nx.DiGraph() # 先批量添加所有节点 G.add_nodes_from(entities) G.add_nodes_from(sornodes) G.add_nodes_from(consumernodes) # 为每个节点匹配颜色 node_color_list = [] for node in G.nodes(): if node in entities: node_color_list.append('yellow') # 实体节点用黄色 elif node in sornodes: node_color_list.append('steelblue') # sor节点用钢蓝色 elif node in consumernodes: node_color_list.append('limegreen') # 消费者节点用青柠绿 else: node_color_list.append('gray') # 其他节点默认灰色
二、给不同边集设置专属颜色
不要一次性绘制所有边,而是分别绘制不同的边集,给每个边集指定专属颜色,这样能清晰区分masters、consumers、ads三种边:
# 假设你的三个边集合已经定义:masters, consumers, ads G.add_edges_from(masters) G.add_edges_from(consumers) G.add_edges_from(ads) # 先计算一次节点布局(所有绘图共用同一个布局,避免节点位置混乱) pos = nx.spring_layout(G) # 分别绘制三种边,指定颜色和箭头样式 nx.draw_networkx_edges(G, pos, edgelist=masters, edge_color='#ff4444', arrowstyle='->', arrowsize=20) nx.draw_networkx_edges(G, pos, edgelist=consumers, edge_color='#ffa500', arrowstyle='->', arrowsize=20) nx.draw_networkx_edges(G, pos, edgelist=ads, edge_color='#9932cc', arrowstyle='->', arrowsize=20)
三、解决图片保存为空、弹出空窗口的问题
你之前的代码问题出在:
- 重复调用绘图函数(先调用
nx.draw_networkx_nodes/edges/labels,又调用nx.draw_spring),导致创建了多个绘图窗口; - 在绘图之后才创建新的
plt.figure,保存的是空的新画布。
正确流程是:先创建画布,再执行所有绘图操作,最后保存并显示。
完整修正后的代码
把上面的部分整合起来,完整代码如下:
import networkx as nx import matplotlib.pyplot as plt # ---------------------- # 替换成你的实际节点和边数据 entities = ["entity_01", "entity_02"] sornodes = ["sor_01", "sor_02"] consumernodes = ["consumer_01", "consumer_02"] masters = [("app_01", "entity_01"), ("app_02", "entity_02")] consumers = [("app_01", "consumer_01"), ("app_02", "consumer_02")] ads = [("sor_01", "app_01"), ("sor_02", "app_02")] # ---------------------- G = nx.DiGraph() # 添加所有节点 G.add_nodes_from(entities) G.add_nodes_from(sornodes) G.add_nodes_from(consumernodes) # 为节点分配颜色 node_color_list = [] for node in G.nodes(): if node in entities: node_color_list.append('yellow') elif node in sornodes: node_color_list.append('steelblue') elif node in consumernodes: node_color_list.append('limegreen') else: node_color_list.append('gray') # 添加所有边 G.add_edges_from(masters) G.add_edges_from(consumers) G.add_edges_from(ads) # 创建大尺寸画布(可随意调大,不受显示器尺寸限制) plt.figure(figsize=(18, 12)) # 比如18x12英寸,适合生成高清大尺寸图片 # 计算节点布局(k参数可调整节点间距,按需修改) pos = nx.spring_layout(G, k=0.15) # 绘制节点 nx.draw_networkx_nodes(G, pos, node_size=1700, node_color=node_color_list) # 分别绘制三种边 nx.draw_networkx_edges(G, pos, edgelist=masters, edge_color='#ff4444', arrowstyle='->', arrowsize=20) nx.draw_networkx_edges(G, pos, edgelist=consumers, edge_color='#ffa500', arrowstyle='->', arrowsize=20) nx.draw_networkx_edges(G, pos, edgelist=ads, edge_color='#9932cc', arrowstyle='->', arrowsize=20) # 绘制节点标签 nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold') # 保存图片:dpi设高保证清晰度,bbox_inches='tight'防止标签被裁剪 plt.savefig('out.png', dpi=300, bbox_inches='tight') # 显示图形(只会弹出一个窗口) plt.show()
关键注意点
- 所有绘图操作必须在同一个
plt.figure下进行,不要重复调用nx.draw_spring这类会自动创建新画布的函数; - 调整
figsize数值可以设置图片的实际尺寸,数值越大生成的图片越大; dpi参数控制图片清晰度,300以上适合打印或高清显示;bbox_inches='tight'一定要加,否则节点标签可能会被裁剪出图片外。
内容的提问来源于stack exchange,提问作者Vasuvius
相关产品推荐
相关产品推荐

