查看全课大纲(第 35 / 45 节)

网络关系图

小象实战讲义 · ECharts 数据可视化

在数据分析中,我们常常需要探索实体之间的关系,例如社交网络中的用户互动、论文中的作者合作、供应链中的企业关联等。这些关系错综复杂,难以用传统的柱状图或折线图清晰表达。本节将学习如何使用 网络关系图,将这种非结构化的网络数据转化为直观的可视化图表,帮助你洞察数据背后的连接模式与结构。

💡 核心导读

  • 理解网络图构成:网络图由节点和连接两个核心元素构成,分别代表实体和它们之间的关系。
  • 掌握数据准备:学会将你的关系型数据(如社交网络、人物关系)处理成 nodes(节点列表)和 links(连接列表)的标准格式。
  • 配置基础网络图:使用 pyecharts 的 Graph 类,通过 repulsion(斥力因子)等参数控制图表的布局与美观度。
  • 进阶图表制作:学习制作带边属性(如关系强度)和带类别(如不同社群)的网络图,以承载更丰富的信息。

1. 认识网络关系图

网络关系图,也称为图或网络,是一种使用节点(或顶点)和连接线(或边)来显示事物之间连接关系的可视化工具。它擅长阐明一组实体之间的关系类型,尤其适用于描述社交网络、知识图谱、交通网络等具有复杂关系结构的场景。

想象一下你的家庭关系、微博上的关注与转发链,或者一本书中的人物互动,这些都可以抽象成一个网络。网络图的核心价值在于,它将抽象的“关系”变成了视觉上可追踪的“连线”。

在 pyecharts 中,我们使用 Graph 图表类型来绘制网络关系图。其底层依赖于 ECharts 的 graph 系列。请注意,本节使用的 pyecharts 版本为 2.1.0,其默认加载的 ECharts 资源版本为 6。

2. 绘制基础网络关系图

绘制网络图的第一步,是将数据准备成标准格式。任何网络图都需要两个基本的数据结构:nodes(节点列表)和 links(连接列表)。

2.1 准备节点与连接数据

nodes 是一个列表,其中每个元素是一个字典,描述一个节点。最基本的属性是 name(节点名称)。links 也是一个列表,每个元素是一个字典,描述一条从源节点指向目标节点的连接,必须包含 source 和 target 两个键,其值对应 nodes 中某个节点的 name。

下面的代码创建了5个节点,并生成了一个“全连接”网络(即每个节点都与其他所有节点相连,包括自身)。

# 导入必要的库
from pyecharts import options as opts
from pyecharts.charts import Graph

# 1. 准备节点数据
nodes = [
    {"name": "结点1", "symbolSize": 10},
    {"name": "结点2", "symbolSize": 20},
    {"name": "结点3", "symbolSize": 30},
    {"name": "结点4", "symbolSize": 40},
    {"name": "结点5", "symbolSize": 50},
]

# 2. 准备连接数据(全连接示例)
links = []
for i in nodes:
    for j in nodes:
        links.append({"source": i["name"], "target": j["name"]})

# 打印连接数据,观察结构
print("连接数据 links 的长度:", len(links))
print("前3条连接示例:", links[:3])

印刷输出:

连接数据 links 的长度: 25
前3条连接示例: [{'source': '结点1', 'target': '结点1'}, {'source': '结点1', 'target': '结点2'}, {'source': '结点1', 'target': '结点3'}]

注意:pyecharts(基于 ECharts)默认不便于绘制节点的“自连接”(即 source 和 target 是同一个节点)。虽然数据中可以包含,但可视化时通常不会有效显示。网络图主要用于展示不同节点间的联系。

2.2 绘制图表与理解“斥力因子”

有了标准格式的数据,就可以用 Graph().add() 方法绘制图表。一个关键的布局参数是 repulsion(斥力因子)。

# 3. 绘制基础网络关系图
chart = (
    Graph()
    .add(
        series_name="",  # 系列名称,可为空
        nodes=nodes,
        links=links,
        repulsion=50,  # 斥力因子,控制节点间的排斥力
        edge_symbol=["none", "arrow"],  # 在连线目标端显示箭头
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="基础网络关系图"))
)

# 生成HTML文件(本地查看用)
chart.render("basic_graph.html")
print(f"图表类型: {type(chart).__name__}")
print("图表标题: 基础网络关系图")
print("图表已生成,可使用浏览器打开 basic_graph.html 查看交互效果。")

印刷输出:

图表类型: Graph
图表标题: 基础网络关系图
图表已生成,可使用浏览器打开 basic_graph.html 查看交互效果。

关键参数解读:repulsion(斥力因子)

  • 作用:这是一个力引导布局参数,值越大,节点之间的排斥力越强,节点在画布上会分布得越开。
  • 使用场景:当节点数量很多时,较小的 repulsion 值可能导致节点重叠、遮挡。适当调大此值(如设为 4000 或 8000)可以帮助生成布局更清晰、美观的图形。
  • 体验建议:在 Jupyter Notebook 环境外,你可以通过修改 repulsion 的值并重新运行代码,观察生成的 HTML 文件中节点布局的变化。

在生成的图表中,你可以将鼠标悬停在任意节点或连线上,pyecharts 会显示相应的信息。连线上的箭头指示了关系的方向(从 source 指向 target)。

3. 绘制带边属性的网络关系图

在实际应用中,节点之间的“关系”本身可能带有属性,例如社交互动的次数、货物运输的成本、合作关系的强度等。我们可以将这些属性赋予“边”,并在图上展示出来。

pyecharts 提供了更规范的数据类来构建这类图表:opts.GraphNode 用于构建节点,opts.GraphLink 用于构建带属性的连接。

from pyecharts import options as opts
from pyecharts.charts import Graph

# 1. 使用 GraphNode 和 GraphLink 准备数据
nodes_data = [
    opts.GraphNode(name="结点1", symbol_size=10),
    opts.GraphNode(name="结点2", symbol_size=20),
    opts.GraphNode(name="结点3", symbol_size=30),
    opts.GraphNode(name="结点4", symbol_size=40),
    opts.GraphNode(name="结点5", symbol_size=50),
]

# 创建一个环状连接,并为每条边赋予一个值 (value)
links_data = [
    opts.GraphLink(source="结点1", target="结点2", value=2),
    opts.GraphLink(source="结点2", target="结点3", value=3),
    opts.GraphLink(source="结点3", target="结点4", value=4),
    opts.GraphLink(source="结点4", target="结点5", value=5),
    opts.GraphLink(source="结点5", target="结点1", value=6),
]

# 2. 绘制带边属性的网络图
chart_with_edge = (
    Graph()
    .add(
        series_name="",
        nodes=nodes_data,
        links=links_data,
        repulsion=4000,
        # 配置边标签 (edge_label)
        edge_label=opts.LabelOpts(
            is_show=True,          # 显示标签
            position="middle",     # 标签位置在线的中间
            formatter="{b} 的数据 {c}"  # 标签格式:b是数据项名称,c是数据值
        ),
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="带边属性的网络关系图"))
)

chart_with_edge.render("graph_with_edge.html")
print(f"边属性图表已生成。连接数量: {len(links_data)}")
print("边标签格式示例: '结点1 > 结点2 的数据 2'")
网络关系图,节点带名称标签、连线标注互动次数
图:带边属性的关系图:节点显示名称,连线标注互动次数,节点大小表示权重。手机端可左右滑动查看,点击图片可看全图。

印刷输出:

边属性图表已生成。连接数量: 5
边标签格式示例: '结点1 > 结点2 的数据 2'

在这张图中,每条连接线上都直接显示了其 value 值。edge_label 的 formatter 参数让你可以自定义标签的显示内容,其中 {b} 对应数据项名称。GraphLink 未单独命名时,ECharts 会把连接自动命名为 source > target,例如 结点1 > 结点2;{c} 对应数据值(即我们设置的 value)。

4. 绘制带类别的网络关系图

在更复杂的网络(如大型社交网络)中,节点往往属于不同的群体或类别。例如,微博转发网络中,用户可能根据其转发的核心源头(如“新浪体育”、“人民日报”)形成不同群落。用不同颜色区分这些类别,能使网络结构一目了然。

这类图表需要三个数据部分:nodes、links 和 categories(类别列表)。每个节点需要通过 category 属性(索引值)声明其所属类别。

下面用一组固定的迷你微博转发数据直接演示。categories 是类别列表,每个节点的 category 值是该列表的索引。

from pyecharts import options as opts
from pyecharts.charts import Graph

categories = [{"name": "体育"}, {"name": "科技"}, {"name": "财经"}]
nodes = [
    {"name": "体育源", "symbolSize": 35, "category": 0},
    {"name": "科技源", "symbolSize": 35, "category": 1},
    {"name": "财经源", "symbolSize": 35, "category": 2},
    {"name": "用户A", "symbolSize": 18, "category": 0},
    {"name": "用户B", "symbolSize": 16, "category": 0},
    {"name": "用户C", "symbolSize": 20, "category": 1},
    {"name": "用户D", "symbolSize": 17, "category": 1},
    {"name": "用户E", "symbolSize": 19, "category": 2},
]
links = [
    {"source": "体育源", "target": "用户A"},
    {"source": "体育源", "target": "用户B"},
    {"source": "科技源", "target": "用户C"},
    {"source": "科技源", "target": "用户D"},
    {"source": "财经源", "target": "用户E"},
    {"source": "用户A", "target": "用户C"},
]

chart_with_category = (
    Graph()
    .add(
        series_name="",
        nodes=nodes,
        links=links,
        categories=categories,  # 传入类别定义
        repulsion=50,
        linestyle_opts=opts.LineStyleOpts(curve=0.2),  # 设置连线为轻微曲线,更美观
        label_opts=opts.LabelOpts(is_show=False),     # 节点太多,默认不显示名称
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="迷你微博转发关系图(带类别)"),
        legend_opts=opts.LegendOpts(is_show=False),   # 类别多时,可关闭图例避免遮挡
    )
)

chart_with_category.render("graph_with_category.html")
print(f"节点数量: {len(nodes)}")
print(f"连接数量: {len(links)}")
print(f"类别数量: {len(categories)}")
print("带类别的网络图已生成。")
print("提示:不同颜色的节点代表不同的转发源头类别。")

印刷输出:

节点数量: 8
连接数量: 6
类别数量: 3
带类别的网络图已生成。
提示:不同颜色的节点代表不同的转发源头类别。

打开生成的 HTML 文件,你会看到节点被渲染成不同的颜色,每个颜色对应一个类别(即一个微博信息源)。力引导布局会让联系紧密的节点(同一类别内转发频繁)聚集在一起,而不同类别之间通过少量的“桥梁”连接。将鼠标悬停在某个中心节点上,高亮显示的将是与其直接相连的所有节点和边,这非常有助于分析某个信息源的影响力范围。

📝 动手练一练

  1. 调整布局体验:将“基础网络关系图”示例代码中的 repulsion 参数依次修改为 10、2000、8000,分别生成 HTML 文件并在浏览器中打开。观察并描述节点布局随着斥力因子增大发生了怎样的变化。
点击查看参考答案

回答要点:

  • 当 repulsion=10 时,节点间排斥力很弱,所有节点可能会紧密聚集甚至重叠在画布中心,难以区分。
  • 当 repulsion=2000 时,排斥力适中,节点会均匀分散在画布上,形成较为清晰的网络结构,连线也不过于杂乱。
  • 当 repulsion=8000 时,排斥力非常强,节点会尽可能远离彼此,甚至被推到画布的边缘,网络结构被拉伸,连线变得很长。
  • 结论:repulsion 是控制网络图布局美观度的关键参数,需要根据节点数量和期望的视觉效果进行反复调试,通常选择一个能让节点清晰分开且不过度分散的中间值。
  1. 创建小型社交网络:请你模拟一个包含4位朋友(A, B, C, D)的小型社交网络。已知关注关系为:A关注B和C,B关注C和D,C关注A,D关注A和B。请编写代码,构建 nodes 和 links 数据,并绘制一张网络图。尝试将“关注”这一关系的强度(假设是互动频率)用边的 value 表示(可自定义数值),并显示在连线上。
点击查看参考答案
from pyecharts import options as opts
from pyecharts.charts import Graph

# 定义节点
nodes = [
    opts.GraphNode(name="A", symbol_size=20),
    opts.GraphNode(name="B", symbol_size=20),
    opts.GraphNode(name="C", symbol_size=20),
    opts.GraphNode(name="D", symbol_size=20),
]

# 定义连接(关注关系)及属性(互动频率)
links = [
    opts.GraphLink(source="A", target="B", value=5),
    opts.GraphLink(source="A", target="C", value=3),
    opts.GraphLink(source="B", target="C", value=8),
    opts.GraphLink(source="B", target="D", value=2),
    opts.GraphLink(source="C", target="A", value=4),
    opts.GraphLink(source="D", target="A", value=6),
    opts.GraphLink(source="D", target="B", value=1),
]

# 绘制图表
chart = (
    Graph()
    .add(
        "",
        nodes,
        links,
        repulsion=3000,
        edge_label=opts.LabelOpts(is_show=True, position="middle", formatter="互动: {c}"),
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="小型社交网络"))
)

chart.render("mini_social_network.html")
print("社交网络图已生成。")

印刷输出:

社交网络图已生成。

打开生成的 HTML 文件,你可以看到清晰的关注关系网络,并且每条线上都标注了假设的互动频率值。

本章小结

本节我们深入学习了网络关系图的原理与实现。网络图是将复杂关系可视化的利器,其核心在于将数据抽象为节点和连接。

📋 行动清单

  • 掌握数据转换:尝试将你手头的一份关系型数据(如项目合作成员表、产品关联购买记录)整理成 nodes 和 links 的列表格式。
  • 实践参数调优:对一个节点数超过20的网络数据,反复调整 repulsion、edge_label 等参数,生成并对比不同布局效果的图表,找到信息可读性与美观度的平衡点。
  • 探索真实场景:思考你所在领域(如金融风控、社区运营、知识管理)中,哪些问题可以建模成网络并用本节所学进行可视化分析。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 10_网络数据及文本数据可视化.ipynb · ECharts 课程配套资源
    IPYNB · 章级代码与输出
    下载
  • weibo.json · ECharts 课程配套资源
    课程配套文件
    下载