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

如何在Streamlit中添加VEGA(非Vega Lite)图表绘制网络?

在Streamlit中使用VEGA绘制网络图的步骤

Streamlit本身没有直接内置VEGA(区别于Vega Lite)的组件,但可以通过st.components.v1.html()嵌入原生VEGA可视化,步骤如下:

1. 准备VEGA网络图规范(Spec)

先定义符合VEGA语法的网络图配置,包含节点(nodes)、链接(links)数据,以及布局、样式设置。比如一个简单的示例spec:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 600,
  "height": 400,
  "padding": 5,
  "signals": [
    {"name": "cx", "update": "width / 2"},
    {"name": "cy", "update": "height / 2"},
    {"name": "nodeRadius", "value": 10},
    {"name": "linkDistance", "value": 100}
  ],
  "data": [
    {
      "name": "nodes",
      "values": [
        {"id": "A", "group": 1},
        {"id": "B", "group": 1},
        {"id": "C", "group": 2},
        {"id": "D", "group": 2},
        {"id": "E", "group": 3}
      ]
    },
    {
      "name": "links",
      "values": [
        {"source": "A", "target": "B"},
        {"source": "B", "target": "C"},
        {"source": "C", "target": "D"},
        {"source": "D", "target": "E"},
        {"source": "E", "target": "A"}
      ]
    }
  ],
  "scales": [
    {
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "nodes", "field": "group"},
      "range": {"scheme": "category10"}
    }
  ],
  "marks": [
    {
      "type": "line",
      "from": {"data": "links"},
      "encode": {
        "update": {
          "x": {"signal": "datum.source.x"},
          "y": {"signal": "datum.source.y"},
          "x2": {"signal": "datum.target.x"},
          "y2": {"signal": "datum.target.y"},
          "stroke": {"value": "#ccc"},
          "strokeWidth": {"value": 1.5}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "nodes"},
      "encode": {
        "enter": {
          "size": {"value": 250},
          "fill": {"scale": "color", "field": "group"},
          "stroke": {"value": "#fff"},
          "strokeWidth": {"value": 1.5}
        },
        "update": {
          "x": {"signal": "datum.x"},
          "y": {"signal": "datum.y"}
        }
      }
    },
    {
      "type": "text",
      "from": {"data": "nodes"},
      "encode": {
        "enter": {
          "text": {"field": "id"},
          "fontSize": {"value": 12},
          "align": {"value": "center"},
          "baseline": {"value": "middle"}
        },
        "update": {
          "x": {"signal": "datum.x"},
          "y": {"signal": "datum.y"}
        }
      }
    }
  ],
  "layouts": [
    {
      "name": "force",
      "type": "force",
      "iterations": 300,
      "velocityDecay": 0.2,
      "nodes": {"data": "nodes"},
      "links": {"data": "links"},
      "static": false,
      "forces": [
        {"force": "center", "x": {"signal": "cx"}, "y": {"signal": "cy"}},
        {"force": "collide", "radius": {"signal": "nodeRadius + 5"}},
        {"force": "link", "distance": {"signal": "linkDistance"}}
      ]
    }
  ]
}

2. 在Streamlit中嵌入VEGA可视化

使用st.components.v1.html()方法,引入VEGA的CDN脚本,然后渲染上述spec:

import streamlit as st
from streamlit.components.v1 import html

# 定义VEGA网络图spec(可替换为自定义数据与配置)
vega_spec = {
    "$schema": "https://vega.github.io/schema/vega/v5.json",
    "width": 600,
    "height": 400,
    "padding": 5,
    "signals": [
        {"name": "cx", "update": "width / 2"},
        {"name": "cy", "update": "height / 2"},
        {"name": "nodeRadius", "value": 10},
        {"name": "linkDistance", "value": 100}
    ],
    "data": [
        {
            "name": "nodes",
            "values": [
                {"id": "A", "group": 1},
                {"id": "B", "group": 1},
                {"id": "C", "group": 2},
                {"id": "D", "group": 2},
                {"id": "E", "group": 3}
            ]
        },
        {
            "name": "links",
            "values": [
                {"source": "A", "target": "B"},
                {"source": "B", "target": "C"},
                {"source": "C", "target": "D"},
                {"source": "D", "target": "E"},
                {"source": "E", "target": "A"}
            ]
        }
    ],
    "scales": [
        {
            "name": "color",
            "type": "ordinal",
            "domain": {"data": "nodes", "field": "group"},
            "range": {"scheme": "category10"}
        }
    ],
    "marks": [
        {
            "type": "line",
            "from": {"data": "links"},
            "encode": {
                "update": {
                    "x": {"signal": "datum.source.x"},
                    "y": {"signal": "datum.source.y"},
                    "x2": {"signal": "datum.target.x"},
                    "y2": {"signal": "datum.target.y"},
                    "stroke": {"value": "#ccc"},
                    "strokeWidth": {"value": 1.5}
                }
            }
        },
        {
            "type": "symbol",
            "from": {"data": "nodes"},
            "encode": {
                "enter": {
                    "size": {"value": 250},
                    "fill": {"scale": "color", "field": "group"},
                    "stroke": {"value": "#fff"},
                    "strokeWidth": {"value": 1.5}
                },
                "update": {
                    "x": {"signal": "datum.x"},
                    "y": {"signal": "datum.y"}
                }
            }
        },
        {
            "type": "text",
            "from": {"data": "nodes"},
            "encode": {
                "enter": {
                    "text": {"field": "id"},
                    "fontSize": {"value": 12},
                    "align": {"value": "center"},
                    "baseline": {"value": "middle"}
                },
                "update": {
                    "x": {"signal": "datum.x"},
                    "y": {"signal": "datum.y"}
                }
            }
        }
    ],
    "layouts": [
        {
            "name": "force",
            "type": "force",
            "iterations": 300,
            "velocityDecay": 0.2,
            "nodes": {"data": "nodes"},
            "links": {"data": "links"},
            "static": false,
            "forces": [
                {"force": "center", "x": {"signal": "cx"}, "y": {"signal": "cy"}},
                {"force": "collide", "radius": {"signal": "nodeRadius + 5"}},
                {"force": "link", "distance": {"signal": "linkDistance"}}
            ]
        }
    ]
}

# 生成嵌入的HTML代码
html_code = f"""
<script src="https://cdn.jsdelivr.net/npm/vega@5.22.1/build/vega.min.js"></script>
<div id="vis"></div>
<script type="text/javascript">
  var spec = {vega_spec};
  var view = new vega.View(vega.parse(spec), {{
    renderer: 'canvas',
    container: '#vis',
    hover: true
  }}).run();
</script>
"""

# 在Streamlit中渲染HTML
html(html_code, width=650, height=450)

3. 自定义调整

  • 修改vega_spec中的data部分,替换成你自己的节点和链接数据
  • 调整width、height、nodeRadius、linkDistance等参数来改变可视化尺寸和布局
  • 修改scales中的range来替换节点颜色方案
  • 可以添加更多交互逻辑到VEGA的spec中,比如点击节点高亮等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:11:06