from pyvis.network import Network
import networkx as nx
import pandas as pd
import os
# 修复模板路径
from pyvis import network as net_module
os.environ["PATH"] += os.pathsep + os.path.dirname(net_module.__file__)
# 创建紧密连接图
g = nx.Graph()
# ========== 关键修复:统一关系字段 ==========
connect_matrix = [
("ACE2受体", "核酸检测", {"关系": "检测靶标", "发现时间": "2020-01"}),
("飞沫传播", "口罩防护", {"关系": "防护方式", "效率": "N95 95%"}),
("发热症状", "CT检查", {"关系": "诊断依据", "准确率": "88%"}),
("灭活疫苗", "科兴生物", {"关系": "研发生产", "有效率": "51%"}),
("Delta变异株", "R0值", {"关系": "传播能力", "数值": "5-8"}),
("核酸检测", "健康码", {"关系": "数据来源", "数据源": "检测结果"}),
("口罩防护", "公共卫生", {"关系": "政策要求", "政策": "强制佩戴"}),
("CT检查", "方舱医院", {"关系": "设备需求", "设备需求": "移动CT车"}),
("科兴生物", "WHO认证", {"关系": "国际认证", "时间": "2021-06"}),
("R0值", "封城措施", {"关系": "决策依据", "关联性": "0.8"}),
]
# 构建核心辐射层(保持不变)
g.add_node("SARS-CoV-2", size=50, color="#FF6F61", group="核心病毒")
core_df = pd.DataFrame({
"核心节点": ["SARS-CoV-2"] * 6,
"关联节点": ["ACE2受体", "飞沫传播", "发热症状", "核酸检测", "灭活疫苗", "Delta变异株"],
"关系类型": ["病毒靶点", "传播途径", "临床表现", "诊断方法", "预防手段", "病毒演化"]
})
for _, row in core_df.iterrows():
g.add_node(row["关联节点"], group=row["关系类型"], size=30)
g.add_edge("SARS-CoV-2", row["关联节点"], title=row["关系类型"], width=3)
# ========== 修复后的连接代码 ==========
for src, tgt, rel in connect_matrix:
# 确保所有节点都存在
if not g.has_node(tgt):
g.add_node(tgt, group="二级概念", size=25, color="#6B5B95")
# 添加带关系的边
g.add_edge(
src,
tgt,
title=rel["关系"], # 确保键存在
**{k: v for k, v in rel.items() if k != "关系"} # 其他属性
)
# 环形连接部分保持不变
ring_connections = [
("健康码", "行程追踪", "基于"),
("行程追踪", "流行病学", "支撑"),
("流行病学", "R0值", "计算"),
("R0值", "封城措施", "影响"),
("封城措施", "方舱医院", "配套"),
("方舱医院", "CT检查", "需要"),
("CT检查", "发热症状", "诊断"),
("发热症状", "ACE2受体", "病理机制")
]
for i, (src, tgt, rel) in enumerate(ring_connections):
g.add_edge(src, tgt, title=rel, color="#888" if i % 2 else "#444")
# 可视化配置和生成代码保持不变
net = Network(height="800px", width="100%", notebook=True)
net.from_nx(g)
net.set_options("""
{
"physics": {
"forceAtlas2Based": {
"gravitationalConstant": -200,
"centralGravity": 0.005,
"springLength": 150,
"avoidOverlap": 0.5
},
"minVelocity": 0.75,
"solver": "forceAtlas2Based"
},
"nodes": {
"scaling": {
"min": 20,
"max": 50
}
}
}
""")
output_path = "COVID19_Dense_Graph_Fixed.html"
net.show(output_path)
os.startfile(os.path.abspath(output_path))
效果如下,可进行物理效果的拉伸、旋转等: