如何用Python和NetworkX绘制学生和教师关系图

665次阅读
没有评论

共计 3605 个字符,预计需要花费 10 分钟才能阅读完成。

提醒:本文最后更新于 2023-10-07 17:33,文中所关联的信息可能已发生改变,请知悉!

在这篇文章中,我将介绍如何用 Python 和 NetworkX 库来绘制一个学生和教师之间的关系图,以及如何查询两个节点之间的关系路径。这个关系图可以很好的帮助我们了解学生和教师之间的联系,以及他们所参与的课程和活动。

准备工作

首先,我们需要安装 Python 和 NetworkX 库。Python 是一种广泛使用的编程语言,它有很多强大的功能和丰富的库。NetworkX 是一个用于创建、操作和分析复杂网络的 Python 库,它提供了很多方便的函数和算法。我们可以用 pip 命令来安装这两个库:

pip install python
pip install networkx

然后,我们需要导入 NetworkX 库和 matplotlib.pyplot 模块。matplotlib.pyplot 是一个用于绘制图形的模块,它可以与 NetworkX 配合使用,让我们可以可视化网络结构。我们可以用 import 语句来导入这两个模块:

import networkx as nx
import matplotlib.pyplot as plt

创建图

接下来,我们需要创建一个有向图对象,并向其中添加节点和边。有向图是一种网络结构,它由节点(也叫顶点)和边(也叫弧)组成,每条边都有一个方向,表示从一个节点指向另一个节点。我们可以用 nx.DiGraph() 函数来创建一个空的有向图对象,并赋值给变量 G:

G = nx.DiGraph()

然后,我们需要定义节点和边的数据。在这个例子中,我们假设有三个学生(张三、李四、王五),三个教师(周老师、梁老师、凌老师),以及他们所参与的课程和活动(AI 实训中心、鑫华楼 207、明华楼 345、智慧技术概论、数据结构、自然语言处理、周二、周三、周四)。我们可以用列表来存储这些数据,并赋值给变量 nodesedges

# 定义节点
nodes = [" 张三 ", " 李四 ", " 周老师 ", " 梁老师 ", "AI 实训中心 ", " 鑫华楼 207",
         " 智慧技术概论 ", " 数据结构 ", " 周三 ", " 周二 ", " 王五 ", " 凌老师 ", " 周四 "]

# 定义边
edges = [(" 张三 ", " 周老师 "),
    (" 李四 ", " 周老师 "),
    (" 王五 ", " 凌老师 "),
    (" 王五 ", " 周老师 "),
    (" 张三 ", " 凌老师 "),
    (" 李四 ", " 凌老师 "),
    (" 周三 ", "AI 实训中心 "),
    (" 周四 ", " 明华楼 345"),
    ("AI 实训中心 ", " 智慧技术概论 "),
    (" 明华楼 345", " 自然语言处理 "),
    (" 李四 ", " 梁老师 "),
    (" 张三 ", " 梁老师 "),
    (" 周二 ", " 鑫华楼 207"),
    (" 鑫华楼 207", " 数据结构 "),
    (" 周老师 ", " 周三 "),
    (" 梁老师 ", " 周二 "),
    (" 凌老师 ", " 周四 "),
]

# 定义节点位置
pos = {" 张三 ": (0, 1),
    " 李四 ": (0, 0),
    " 王五 ": (0, -1),
    " 周老师 ": (2, 0),
    " 梁老师 ": (2, 2),
    " 凌老师 ": (2, -2),
    "AI 实训中心 ": (4, 0),
    " 鑫华楼 207": (4, 2),
    " 明华楼 345": (4, -2),
    " 智慧技术概论 ": (6, 0),
    " 数据结构 ": (6, 2),
    " 自然语言处理 ": (6, -2),
    " 周四 ": (3, -2),
    " 周三 ": (3, 0),
    " 周二 ": (3, 2),
}

接着,我们需要将节点和边添加到图中。我们可以用 G.add_nodes_from() 函数来添加节点列表,用 G.add_edges_from() 函数来添加边列表:

# 将节点添加到图中
G.add_nodes_from(nodes)

# 将边添加到图中
G.add_edges_from(edges)

绘制图

最后,我们需要绘制图,并显示节点和边的标签。我们可以用 plt.figure() 函数来创建一个图形对象,并指定大小。然后,我们可以用 plt.rcParams[] 字典来设置字体,以便显示中文。再用 nx.draw_networkx_nodes() 函数来绘制节点,并指定颜色和大小。用 nx.draw_networkx_edges() 函数来绘制边,并指定颜色、宽度和透明度。最后用 nx.draw_networkx_labels() 函数来绘制节点标签,并添加偏移以避免重叠。当然,我们也可以用 plt.title() 函数来添加标题,用 plt.axis() 函数来关闭坐标轴。代码如下:

plt.figure(figsize=(12, 8))
plt.rcParams['font.sans-serif'] = ['simHei']

# 绘制节点,指定颜色和大小
nx.draw_networkx_nodes(G, pos, node_color='lightblue', node_size=500)

# 绘制边
nx.draw_networkx_edges(G, pos, edge_color='gray', width=1.0, alpha=0.7)

# 绘制节点标签,并添加偏移以避免重叠
node_labels = {node: node for node in G.nodes()}
node_label_pos = {k: (v[0], v[1] + 0.1)
                  for k, v in pos.items()}  # 在 y 轴上添加 0.1 的偏移
nx.draw_networkx_labels(G, node_label_pos, labels=node_labels, font_size=12)

# 自定义图的外观
plt.title('学生和教师关系图')
plt.axis('off')

查询关系

除了绘制图之外,我们还可以用 NetworkX 库提供的一些函数和算法来查询两个节点之间的关系路径。例如,我们可以用 nx.all_simple_paths() 函数来找出从一个节点到另一个节点的所有简单路径(不重复经过任何节点的路径)。我们可以将这个函数封装在一个自定义的函数中,命名为 find_relationship(),并接受两个参数:node1node2,分别表示起点和终点。在这个函数中,我们首先用 list() 函数将 nx.all_simple_paths() 函数的返回值转换为一个列表,并赋值给变量 paths。然后,我们判断paths 是否为空,如果不为空,则表示存在关系路径,我们就打印出每条路径,并在图上显示查询结果;如果为空,则表示不存在关系路径,我们就打印出提示信息,并在图上显示查询结果。代码如下:

# 查找两个节点之间的关系
def find_relationship(node1, node2):
    paths = list(nx.all_simple_paths(G, source=node1, target=node2))
    if paths:
        print(f" 从 {node1} 到 {node2} 的关系路径:")
        for path in paths:
            print(" -> ".join(path))
        # 在图上显示查询结果
        result_text = f" 从 {node1} 到 {node2} 的关系路径:\n"
        result_text += "\n".join([" -> ".join(path) for path in paths])
        plt.annotate(result_text, xy=(0, 0), xycoords='axes fraction', fontsize=12,
                     bbox=dict(boxstyle="round,pad=0.5", edgecolor="blue", facecolor="lightyellow"))
    else:
        result_text = f"{node1} 和 {node2} 之间不存在关系。"
        plt.annotate(result_text, xy=(0, 0), xycoords='axes fraction', fontsize=12,
                     bbox=dict(boxstyle="round,pad=0.5", edgecolor="blue", facecolor="lightyellow"))
        print(result_text)

示例查询

为了演示这个函数的效果,我们可以用一个示例查询来调用它。例如,我们可以查询王五和自然语言处理之间的关系路径:

# 示例查询
find_relationship(" 王五 ", " 自然语言处理 ")

运行这段代码后,我们可以看到输出结果如下:

从 王五到 自然语言处理 的关系路径:
王五 -> 凌老师 -> 周四 -> 明华楼 345 -> 自然语言处理

我们还可以使用 plt.show() 看到图上显示了查询结果:

plt.show()

如下图所示:

如何用 Python 和 NetworkX 绘制学生和教师关系图

总结

通过这篇文章,我们学习了如何用 PythonNetworkX库来绘制一个学生和教师之间的关系图,以及如何查询两个节点之间的关系路径。这个关系图可以帮助我们了解学生和教师之间的联系,以及他们所参与的课程和活动。我们还可以用 NetworkX 库提供的一些函数和算法来分析网络结构的特征,例如度数、聚类系数、最短路径、连通性等。如果你对这些内容感兴趣,可以参考 NetworkX 官方文档NetworkX 教程 来进一步学习。

正文完
 0
历史的配角
版权声明:本站原创文章,由 历史的配角 于2023-09-19发表,共计3605字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码

您无法复制此页面的内容

了解 未来日记 的更多信息

立即订阅以继续阅读并访问完整档案。

Continue reading