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

加权有向用户行为图布局计算:Python可识别瓶颈与路径的可视化方案求助

加权用户行为有向图可视化优化方案(Python实现)

针对你遇到的强连通图布局混乱、无法直观识别瓶颈和热门路径的问题,结合start/end节点的特性,以下是几个实用的优化思路和代码实现:

1. 强制层级布局(适配流程方向)

利用start和end节点定义明确的流程起点终点,禁用默认的力导向布局,改用层级垂直布局(上下方向),让节点按流量流向从start到end依次排列,避免强连通带来的交叉混乱。

2. 视觉编码突出核心信息

通过节点大小、颜色,边的宽度、透明度,直接映射流量和瓶颈属性:

  • 节点大小:正比于节点的总流量(入站+出站用户数)
  • 节点颜色:区分start/end,并用冷暖色表示瓶颈程度(入站远大于出站为红色瓶颈,出站远大于入站为蓝色分流)
  • 边的宽度/透明度:正比于跳转用户数,低权重边透明化减少视觉干扰

3. 交互式可视化(PyVis实现)

静态图难以处理大量边,用PyVis生成交互式HTML,支持缩放、拖拽、悬停查看详情,方便自由探索。

完整代码示例

import networkx as nx
from pyvis.network import Network

# 替换为你的真实图数据(示例模拟)
G = nx.DiGraph()
G.add_nodes_from(['start', 'page_a', 'page_b', 'page_c', 'page_d', 'end'])
G.add_edges_from([
    ('start', 'page_a', {'weight': 1200}),
    ('start', 'page_b', {'weight': 950}),
    ('page_a', 'page_c', {'weight': 1100}),
    ('page_b', 'page_c', {'weight': 800}),
    ('page_c', 'page_d', {'weight': 1500}),
    ('page_d', 'end', {'weight': 1400}),
    ('page_c', 'page_a', {'weight': 200}),  # 模拟强连通边
    ('page_d', 'page_b', {'weight': 150})   # 模拟强连通边
])

# 计算节点总流量(入站+出站)
node_flow = {}
for node in G.nodes:
    in_flow = sum(d['weight'] for _, _, d in G.in_edges(node, data=True))
    out_flow = sum(d['weight'] for _, _, d in G.out_edges(node, data=True))
    node_flow[node] = in_flow + out_flow

# 归一化边权重,用于设置边宽
max_weight = max(d['weight'] for _, _, d in G.edges(data=True))
min_weight = min(d['weight'] for _, _, d in G.edges(data=True))
norm_weight = lambda w: (w - min_weight)/(max_weight - min_weight)*10 + 1  # 边宽范围1-11

# 创建交互式有向图
net = Network(directed=True, height='900px', width='100%')

# 添加节点:设置大小、颜色、悬停提示
for node in G.nodes:
    # 节点大小映射总流量
    size = (node_flow[node]/max(node_flow.values()))*60 + 20
    # 节点颜色设置
    if node == 'start':
        color = '#27ae60'
    elif node == 'end':
        color = '#2980b9'
    else:
        # 计算瓶颈得分:(入流量-出流量)/最大流量,正数为瓶颈
        in_flow = sum(d['weight'] for _, _, d in G.in_edges(node, data=True))
        out_flow = sum(d['weight'] for _, _, d in G.out_edges(node, data=True))
        bottleneck = (in_flow - out_flow)/max(in_flow, out_flow, 1)
        # 颜色从蓝(分流)到红(瓶颈)渐变
        if bottleneck > 0:
            r, g, b = 255, int(255*(1-bottleneck)), int(255*(1-bottleneck))
        else:
            r, g, b = int(255*(1+bottleneck)), int(255*(1+bottleneck)), 255
        color = f'#{r:02x}{g:02x}{b:02x}'
    net.add_node(node, size=size, color=color, title=f"总流量: {node_flow[node]}")

# 添加边:设置宽度、透明度、悬停提示
for u, v, d in G.edges(data=True):
    w = d['weight']
    net.add_edge(
        u, v,
        width=norm_weight(w),
        color=f'rgba(0,0,0, {w/max_weight})',  # 权重越高越不透明
        title=f"跳转用户数: {w}"
    )

# 配置层级布局,禁用混乱的力导向
net.set_options("""
{
  "physics": { "enabled": false },
  "layout": {
    "hierarchical": {
      "enabled": true,
      "direction": "UD",
      "sortMethod": "directed",
      "nodeSpacing": 150,
      "treeSpacing": 200
    }
  }
}
""")

# 保存为交互式HTML文件
net.write_html('user_path_visualization.html')

4. 边过滤简化(可选)

如果1500条边仍显杂乱,可过滤掉低权重边(比如只保留权重前20%的边),或者提取start到end的热门路径单独可视化:

# 过滤低权重边,保留权重前20%
edge_weights = [(u, v, d['weight']) for u, v, d in G.edges(data=True)]
edge_weights.sort(key=lambda x: x[2], reverse=True)
keep_count = int(len(edge_weights)*0.2)
filtered_edges = [(u, v, {'weight': w}) for u, v, w in edge_weights[:keep_count]]

# 构建简化图
filtered_G = nx.DiGraph()
filtered_G.add_nodes_from(G.nodes)
filtered_G.add_edges_from(filtered_edges)

# 重复上述可视化流程即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:59:51