如何在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
相关产品推荐
相关产品推荐

