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

如何从pm4py生成的graphviz.Digraph提取位置或转换为带位置的NetworkX对象

从PM4Py生成的Graphviz Digraph提取节点位置并转换为带位置信息的NetworkX图

问题描述

通过PM4Py生成graphviz.graphs.Digraph对象(示例中的gviz)后,需要从中提取节点位置信息,或直接转换为包含位置属性的NetworkX图对象。尝试设置FORMAT: 'dot'参数无效果,查看gviz.source发现位置信息存储在长数字串中,但无法直接转换为NetworkX的pos属性所需的(x,y)坐标。

解决方案

解析Graphviz生成的DOT源码,提取节点位置,再构建对应的NetworkX图并关联位置信息。具体实现如下:

完整代码

import pm4py
import pandas as pd
import networkx as nx
from pm4py.objects.conversion.log import converter as log_converter
from pm4py.visualization.dfg import visualizer as dfg_visualization
import re

# 生成示例事件日志(原代码)
time = []
for i in range(14):
    time.append(pd.to_datetime('2022-01-01') + pd.Timedelta(days=i))

df = pd.DataFrame({
    'case:concept:name': ['A','A','A','A',
                          'B','B','B','B',
                          'C','C','C',
                          'D','D','D'],
    'concept:name': ['Task 1', 'Task 2', 'Task 3', 'Task 5',
                     'Task 1', 'Task 2', 'Task 4', 'Task 5',
                     'Task 1', 'Task 3', 'Task 5',
                     'Task 1', 'Task 2', 'Task 5'],
    'time:timestamp': time
})

event_log = log_converter.apply(df)
dfg, _, _ = pm4py.discover_dfg(event_log)
gviz = dfg_visualization.apply(dfg, log=event_log)

# 核心转换函数
def convert_pm4py_gviz_to_networkx_with_positions(gviz):
    dot_source = gviz.source
    G = nx.DiGraph()
    pos = {}
    
    # 匹配节点ID和位置坐标的正则
    node_regex = re.compile(r'\"([^\"]+)\" \[.*pos=\"([\d.]+),([\d.]+)\".*\]')
    # 匹配边的正则
    edge_regex = re.compile(r'\"([^\"]+)\" -> \"([^\"]+)\"')
    
    # 提取节点与位置
    for match in node_regex.finditer(dot_source):
        node = match.group(1)
        x = float(match.group(2))
        y = float(match.group(3))
        # 反转y轴,对齐NetworkX与Graphviz的布局方向
        pos[node] = (x, -y)
        G.add_node(node)
    
    # 提取边
    for match in edge_regex.finditer(dot_source):
        src_node = match.group(1)
        dst_node = match.group(2)
        G.add_edge(src_node, dst_node)
    
    return G, pos

# 执行转换
G, pos = convert_pm4py_gviz_to_networkx_with_positions(gviz)

# 验证:用NetworkX绘制带位置的图
import matplotlib.pyplot as plt
nx.draw(G, pos, with_labels=True, node_size=1500, font_size=10)
plt.show()

关键说明

  • 正则表达式分别匹配DOT源码中的节点定义和边定义,提取节点ID、位置坐标以及边的连接关系
  • Graphviz的y轴方向向下,NetworkX默认向上,因此将y坐标取反,保证布局与PM4Py生成的图一致
  • 转换后的G是NetworkX有向图,pos是符合NetworkX要求的位置字典,可直接用于绘图或其他分析

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:01:59