<think>我们正在处理一个关于使用PyVis创建和可视化多向有向图(Multidigraph)的问题。多向有向图允许两个节点之间存在多条有向边(也称为平行边)。PyVis是一个基于网络图的Python库,它使用vis.js来生成交互式网络图。
步骤:
1. 安装PyVis(如果尚未安装)
2. 创建一个有向图(注意:PyVis的Network类默认创建的是无向图,要创建有向图需要设置`directed=True`)
3. 添加节点和边。为了创建多向图(即允许平行边),我们需要使用`multigraph=True`选项。但是请注意,PyVis的Network类在创建时有一个`multigraph`参数,用于支持多图(即多重图,允许节点间有多条边)。
4. 可视化图形。
注意:PyVis的文档提到,当使用多图(multigraph)时,边可以通过添加键(key)来区分同一节点对之间的多条边。但是,在PyVis中,默认情况下,边是通过(源节点,目标节点)来标识的,因此如果不使用键,则同一节点对之间只能有一条边。为了支持多重边,我们需要在添加边时指定一个额外的`key`参数。
然而,根据PyVis的源码和文档,实际上在添加边时,我们可以使用`key`参数来创建多重边。但是,在可视化时,vis.js本身并不直接支持显示多重边(它可能会将多条边合并成一条)。因此,PyVis通过一种方式将多重边显示为弯曲的边(curved edges)来区分。
具体步骤:
- 创建Network对象时,设置`directed=True`和`multigraph=True`。
- 添加节点:`net.add_node(node_id, label=node_label)`
- 添加边时,除了指定`from`和`to`,还要指定`key`(一个唯一的标识符,用于区分同一节点对之间的多条边)和`title`(可选,用于悬停时显示信息)等。
示例代码:
假设我们要创建一个包含两个节点(A和B)的多向有向图,并且A到B有两条边。
注意:在PyVis中,节点可以用整数或字符串标识,但需要保持一致。
但是,需要注意的是,PyVis的交互式可视化在显示多重边时,可能会将多条边显示为弯曲的曲线,以便区分。
另外,由于PyVis是基于vis.js的,而vis.js并不原生支持多图(multigraph),所以PyVis通过将多重边转换为带曲线的边来模拟,这样在视觉上可以区分同一节点对之间的多条边。
因此,我们将按照以下步骤操作:
1. 导入所需模块
2. 创建一个有向的多重图网络
3. 添加节点
4. 添加边(为同一对节点添加多条边时,使用不同的key)
5. 设置一些选项(例如,启用物理效果,使边不重叠)
6. 显示或保存为HTML文件
代码示例:
```python
from pyvis.network import Network
# 创建有向多重图
net = Network(directed=True, multigraph=True)
# 添加节点
net.add_node(1, label="Node 1")
net.add_node(2, label="Node 2")
# 添加两条从节点1到节点2的边,使用不同的key
net.add_edge(1, 2, key="edge1", label="Edge 1", color="blue")
net.add_edge(1, 2, key="edge2", label="Edge 2", color="red", physics=True)
# 设置物理布局,使边分开
net.toggle_physics(True) # 开启物理效果,这样边会自然分开
# 生成并保存为HTML文件
net.show("multidigraph.html", notebook=False)
```
注意:上面的代码中,我们通过`key`参数为同一对节点(1和2)添加了两条边,并分别设置了标签和颜色。`toggle_physics(True)`用于启用物理效果,这样节点和边会根据物理模型进行布局,多条边会自然分开。
但是,请注意,PyVis的物理效果有时可能不会自动将多重边分开得很明显,因此我们可能需要调整边的弯曲程度(通过`curve`参数)或使用其他布局选项。
另一种方法是使用`spring`布局,并设置边的`spring_length`参数。但PyVis中,我们可以通过调整全局布局参数来改善。
另外,我们也可以为每条边设置不同的`weight`(权重)来影响布局,但更直接的方法是调整边的`smooth`属性(控制边的弯曲)和`physics`属性(是否在布局中考虑边的物理属性)。
在PyVis中,边可以通过`smooth`属性来控制弯曲类型。例如,设置`smooth={'type': 'curvedCCW', 'roundness': 0.3}`可以创建弯曲的边。
我们可以修改添加边的代码,为每条边设置不同的弯曲:
```python
net.add_edge(1, 2, key="edge1", label="Edge 1", color="blue", smooth={'type': 'curvedCCW', 'roundness': 0.2})
net.add_edge(1, 2, key="edge2", label="Edge 2", color="red", smooth={'type': 'curvedCW', 'roundness': 0.2})
```
这样,两条边会以不同的弯曲方向(逆时针和顺时针)显示,从而避免重叠。
总结:使用PyVis创建多向有向图的关键点:
1. 在创建Network对象时设置`multigraph=True`。
2. 添加边时使用`key`参数来区分同一对节点之间的多条边。
3. 通过设置边的`smooth`属性或启用物理布局来使多条边在可视化时分开。
现在,我们可以根据上述内容生成回答。
注意:用户要求使用中文回答,并且按照指定的格式要求(如行内数学公式用$...$,独立公式用$$...$$等),但本问题不涉及数学公式,所以主要关注代码和文字描述。
同时,我们需要生成相关问题。
根据用户的问题,我们生成了关于使用PyVis创建和可视化多向有向图的步骤和示例代码。接下来,生成相关问题。</think>### 使用 PyVis 创建和可视化多向有向图(Multidigraph)
以下是创建和可视化多向有向图的完整步骤(基于 PyVis 库):
#### 1. 安装 PyVis
```bash
pip install pyvis
```
#### 2. 创建多向有向图
```python
from pyvis.network import Network
# 创建有向图(启用多重边支持)
net = Network(directed=True, multigraph=True) # 关键参数:multigraph=True
# 添加节点
net.add_node(1, label="A")
net.add_node(2, label="B")
net.add_node(3, label="C")
# 添加多条有向边(相同节点对)
net.add_edge(1, 2, key="edge1", label="关系1", color="blue") # key 区分不同边
net.add_edge(1, 2, key="edge2", label="关系2", color="red")
net.add_edge(2, 3, key="primary", weight=5)
net.add_edge(3, 1, key="feedback", dashes=True)
# 配置可视化选项
net.toggle_physics(True) # 启用物理引擎防止边重叠
net.set_edge_smooth('dynamic') # 动态弯曲边
```
#### 3. 可视化与导出
```python
# 显示在Jupyter中
net.show("multidigraph.html", notebook=True)
# 或保存为独立HTML
net.save_graph("multidigraph.html")
```
#### 关键参数说明
1. **multigraph=True**
启用多重图模式,允许相同节点间存在多条边
2. **key 参数**
必需唯一标识符,用于区分同节点对的边(如 `key="edge1"`)
3. **边属性定制**
- `label`:边标签
- `color`:颜色
- `weight`:线宽权重
- `dashes`:虚线样式
#### 可视化效果优化
```python
# 调整布局
net.force_atlas_2based(gravity=-100) # 增强节点排斥力
# 添加交互功能
net.show_buttons(filter_=['physics']) # 显示物理引擎控制按钮
# 设置弯曲度(避免边重叠)
net.set_edge_smooth('continuous', roundness=0.5)
```
#### 技术注意事项
1. 多重边渲染依赖物理引擎(启用 `toggle_physics(True)`)
2. 每条边必须包含唯一 `key`(字符串或数字)
3. 复杂图建议使用 `BarnesHut` 算法加速布局:
```python
net.barnes_hut(gravity=-5000, central_gravity=0.1)
```
[^1]: 多向图建模常用于社交网络分析、生物通路映射等场景
[^2]: 动态弯曲算法可有效分离重叠边