如何为基于pandas数据生成的Graphviz有向图添加起止节点
实现方案
完全可以实现,你只需先识别原有流程的天然起点和终点,再新增自定义的起止节点并关联对应边即可。
操作逻辑
- 天然起点:仅在
Start Activity列出现、从未在End Activity列出现的节点,是流程的初始触发节点 - 天然终点:仅在
End Activity列出现、从未在Start Activity列出现的节点,是流程的结束节点 - 新增自定义的全局起始、终止节点,分别关联所有天然起点、所有天然终点,即可明确标识整个流程的首尾
修复&修改后的完整代码
import graphviz import pandas as pd Z = graphviz.Digraph(format='jpeg') Z.attr(rankdir='LR') Z.attr('node', shape='circle', color='red', style='filled', fontsize='20', fontcolor='white') Z.attr('edge', arrowhead='vee', arrowtail='inv', color='green', fontcolor='blue') max_node = 5 max_case_id = sortnewtime2['Duration'].max() # 先提取天然起止点 all_start = set(sortnewtime2['Start Activity'].unique()) all_end = set(sortnewtime2['End Activity'].unique()) natural_starts = all_start - all_end natural_ends = all_end - all_start # 新增全局起止节点,自定义样式和原有节点区分 Z.node('S', label='起始', shape='rect', color='#00008B', style='filled', fontcolor='white') Z.node('E', label='终止', shape='rect', color='#006400', style='filled', fontcolor='white') nodelist2 = [] for idx, row in sortnewtime2.iterrows(): node11, node22, weight2 = [str(i) for i in row] # 修复原有代码的bug:原来添加node11后错误追加node22到列表,导致节点可能重复/漏加 if node11 not in nodelist2: Z.node(node11) nodelist2.append(node11) if node22 not in nodelist2: Z.node(node22) nodelist2.append(node22) Z.edge(node11, node22, label = weight2, penwidth=str(float(weight2)/max_case_id*max_node)) # 关联全局起始节点到所有天然起点 for s in natural_starts: Z.edge('S', s, penwidth='2') # 关联所有天然终点到全局终止节点 for e in natural_ends: Z.edge(e, 'E', penwidth='2') Z
效果说明
运行后会自动在现有流程的最左侧添加蓝色矩形的「起始」节点、最右侧添加绿色矩形的「终止」节点,边的样式可以根据需求调整宽度、标签等属性。
内容的提问来源于stack exchange,提问作者nkwachiabel
相关产品推荐
相关产品推荐

