Python 使用 NetworkX

news2024/9/9 4:57:39

Python 使用 NetworkX

说明:本篇文章主要讲述 python 使用 networkx 绘制有向图;

1. 介绍&安装

NetworkX 是一个用于创建、操作和研究复杂网络的 Python 库。它提供了丰富的功能,可以帮助你创建、分析和可视化各种类型的网络,例如社交网络、Web图、生物网络等。NetworkX 可以用来创建各种类型的网络,包括有向图无向图。它提供了各种方法来添加、删除和修改网络中的节点和边。你可以使用节点和边的属性来进一步描述网络的特性。

NetworkX 还提供了许多图的算法和分析工具。你可以使用这些工具来计算各种网络指标,比如节点的度、网络的直径、最短路径等。你还可以使用它来发现社区结构、进行图的聚类分析等。

除了功能强大的操作和分析工具,NetworkX还提供了多种方式来可视化网络。你可以使用它来绘制网络的节点和边,设置节点的颜色、尺寸和标签等。

总的来说,NetworkX是一个功能丰富、灵活易用的Python库,用于创建、操作和研究各种类型的复杂网络。无论你是在进行学术研究、数据分析还是网络可视化,NetworkX都是一个不错的选择。

安装

pip install networkx

2. 简单的有向图绘制

简单的类展示

import networkx as nx  # 导入 NetworkX 工具包
# 创建 图
G1 = nx.Graph()  # 创建:空的 无向图
G2 = nx.DiGraph()  #创建:空的 有向图
G3 = nx.MultiGraph()  #创建:空的 多图
G4 = nx.MultiDiGraph()  #创建:空的 有向多图

三节点有向图的绘制

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 1. 创建有向图对象, 创建空的有向图的对象
G = nx.DiGraph()

# 2. 添加节点
G.add_node('A')
G.add_node('B')
G.add_node('C')

# 3. 添加有向边
G.add_edge('A', 'B')
G.add_edge('B', 'C')

# 4. 进行图的绘制
pos = nx.spring_layout(G)  # 选择布局算法;
nx.draw(G, pos, with_labels=True)
plt.show()

image-20230701225230056

绘制分支节点的有向图

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 1. 创建有向图对象, 创建空的有向图的对象
G = nx.DiGraph()

# 2. 添加节点
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_node('D')
G.add_node('E')

# 3. 添加有向边
G.add_edge('A', 'B')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('C', 'E')


# 4. 进行图的绘制
pos = nx.spring_layout(G)  # 选择布局算法;
nx.draw(G, pos, with_labels=True)
plt.show()

image-20230701225411670

3.有向图的遍历

三节点有向图的遍历

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 1. 创建有向图对象, 创建空的有向图的对象
G = nx.DiGraph()

# 2. 添加节点
G.add_node('A')
G.add_node('B')
G.add_node('C')
# G.add_node('D')
# G.add_node('E')

# 3. 添加有向边
G.add_edge('A', 'B')
G.add_edge('B', 'C')
# G.add_edge('B', 'D')
# G.add_edge('C', 'E')

# 4. 进行图的绘制
pos = nx.spring_layout(G)  # 选择布局算法;
nx.draw(G, pos, with_labels=True)
plt.show()

# 5. 有向图的遍历
print(G.nodes)  # 节点列表, 输出节点 列表
for node in G.nodes():
    print("节点>>>", node)

image-20230701230149897

绘制分支节点图形的输出

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 1. 创建有向图对象, 创建空的有向图的对象
G = nx.DiGraph()

# 2. 添加节点
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_node('D')
G.add_node('E')

# 3. 添加有向边
G.add_edge('A', 'B')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('C', 'E')

# 4. 进行图的绘制
pos = nx.spring_layout(G)  # 选择布局算法;
nx.draw(G, pos, with_labels=True)
plt.show()

# 5. 有向图的遍历
print(G.nodes)  # 节点列表
# print(G.edges)  # 边列表, [('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'E')]
for node in G.nodes():
    print("节点>>>", node)
    in_degree = G.in_degree(node)
    print("入度:", in_degree)
    # 获取节点的出度
    out_degree = G.out_degree(node)
    print("出度:", out_degree)
    # 获取节点的邻居节点
    neighbors = G.neighbors(node)
    print("邻居节点:", list(neighbors))

image-20230701230547282

4.带权重的边

本章节的内容主要展示带权重的边的绘制,并且求取出最大值和最小值;

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 创建有向图
G = nx.DiGraph()
# 直接创建边, 自动添加两个节点, 并且设置边的权重
G.add_edge('A', 'B', weight=3)
G.add_edge('B', 'C', weight=5)
G.add_edge('C', 'D', weight=2)
G.add_edge('C', 'E', weight=5)

pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True)
# 获取边的权重
labels = nx.get_edge_attributes(G, 'weight')
# 绘制带有权重的边
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

plt.show()
# 获取边的权重值列表
weights = nx.get_edge_attributes(G, 'weight').values()
print("边的权重值列表>>>", weights)
max_weight = max(weights)
min_weight = min(weights)

print("最大权重的边:", max_weight)
print("最小权重的边:", min_weight)

image-20230701231846552

求取图形中得最短路径

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt


def get_shortest_path(graph, source, target):
    try:
        shortest_path = nx.shortest_path(graph, source, target)
        return shortest_path
    except nx.exception.NetworkXNoPath:
        return "不存在最短路径"


def get_longest_path(graph, source, target):
    all_paths = nx.all_simple_paths(graph, source, target)
    longest_path = max(all_paths, key=len)
    return longest_path


# 创建有向图
G = nx.DiGraph()
G.add_edge('A', 'B')
G.add_edge('A', 'C')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('C', 'D')
pos = nx.spring_layout(G)  # 选择布局算法;
nx.draw(G, pos, with_labels=True)
plt.show()
# 求取最短路径
shortest_path = get_shortest_path(G, 'A', 'D')
print("最短路径:", shortest_path)

# 求取最长路径
longest_path = get_longest_path(G, 'A', 'D')
print("最长路径:", longest_path)

image-20230701232635408

按照权重求最短路径&最长路径

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 创建有向带权重图
G = nx.DiGraph()
G.add_edge('A', 'B', weight=3)
G.add_edge('A', 'C', weight=5)
G.add_edge('B', 'C', weight=2)
G.add_edge('B', 'D', weight=4)
G.add_edge('C', 'D', weight=1)
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True)
# 获取边的权重
labels = nx.get_edge_attributes(G, 'weight')
# 绘制带有权重的边
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

plt.show()

# 按照权重求取最短路径
shortest_path = nx.dijkstra_path(G, 'A', 'D', weight='weight')
shortest_distance = nx.dijkstra_path_length(G, 'A', 'D', weight='weight')

print("最短路径:", shortest_path)
print("最短距离:", shortest_distance)

image-20230701232954856

import networkx as nx

# 创建有向带权重图
G = nx.DiGraph()
G.add_edge('A', 'B', weight=3)
G.add_edge('A', 'C', weight=5)
G.add_edge('B', 'C', weight=2)
G.add_edge('B', 'D', weight=4)
G.add_edge('C', 'D', weight=1)

# 将边的权重取相反数
G_neg = nx.DiGraph()
for u, v, data in G.edges(data=True):
    G_neg.add_edge(u, v, weight=-data['weight'])

# 按照权重取相反数的图中求取最短路径
longest_path = nx.dijkstra_path(G_neg, 'A', 'D', weight='weight')
longest_distance = -nx.dijkstra_path_length(G_neg, 'A', 'D', weight='weight')

print("最长路径:", longest_path)
print("最长距离:", longest_distance)

5.json 数据的转换

**说明:**前后端交互的时候通常传回的时候的 json 格式化后的数据,通常需要构建一下,因此最好创建一个统一的类进行封装。

# -*- coding: utf-8 -*-
"""图的封装;
"""
import networkx as nx
import matplotlib.pyplot as plt


class GraphDict(object):
    """有向图的构造;
    """

    def __init__(self):
        """初始化的封装;
        """
        self.graph = None  # 有向图的构建
        self.graph_weight = None  # 有向图带权重

    def dict_to_graph(self, data: list):
        """
        图的字典模式;
        :param data:
        :return:

        example:
            data=[{
              source: 'Node 1',
              target: 'Node 3'
            },
            {
              source: 'Node 2',
              target: 'Node 3'
            },
            {
              source: 'Node 2',
              target: 'Node 4'
            },
            {
              source: 'Node 1',
              target: 'Node 4'
            }]
        """
        graph = nx.DiGraph()  # 创建有向图
        # 循环添加边, 直接添加上节点
        for item in data:
            graph.add_edge(item.get('source'), item.get("target"))
        # 赋值并返回
        self.graph = graph
        return graph

    def dict_to_graph_weight(self, data: list):
        """
        图的字典模式, 带权重;
        :param data:
        :return:

        example:
            data = [
                {
                  source: 'Node 1',
                  target: 'Node 3',
                  weight: 5
                },
                {
                  source: 'Node 2',
                  target: 'Node 3',
                  weight: 3,
                },
                {
                  source: 'Node 2',
                  target: 'Node 4',
                  weight: 5,
                },
                {
                  source: 'Node 1',
                  target: 'Node 4',
                  weight: 5
                }
            ]
        """
        graph = nx.DiGraph()  # 创建有向图
        # 循环添加边, 直接添加上节点, 并且为边赋值上权重;
        for item in data:
            graph.add_edge(item.get('source'), item.get("target"), weight=item.get("weight"))
        # 赋值并返回
        self.graph_weight = graph
        return graph

    def graph_to_dict(self):
        """
        图的数据转换成为字典的数据;
        :return:
        """
        assert self.graph is not None or self.graph_weight is not None, "必须首先通过该类创建一个有向图"
        if self.graph is None:
            edges = self.graph_weight.edges(data=True)
            return [{"source": s, "target": t, "weight": w['weight']} for s, t, w in edges]
        else:
            edges = self.graph.edges()
            return [{"source": s, "target": t} for s, t in edges]

    def show(self):
        """
        有向图的显示;
        :return:
        """
        assert self.graph is not None or self.graph_weight is not None, "必须首先通过该类创建一个有向图"
        if self.graph is None:
            pos = nx.spring_layout(self.graph_weight)
            nx.draw(self.graph_weight, pos, with_labels=True)
            labels = nx.get_edge_attributes(self.graph_weight, 'weight')
            nx.draw_networkx_edge_labels(self.graph_weight, pos, edge_labels=labels)
            plt.show()
        else:
            pos = nx.spring_layout(self.graph)
            nx.draw(self.graph, pos, with_labels=True)
            plt.show()

    def to_png(self, name: str):
        """
        导出有向图的 png 图片;
        :param name; str, 想要导出 png 图片的名称;
        :return:
        """
        assert self.graph is not None or self.graph_weight is not None, "必须首先通过该类创建一个有向图"
        if self.graph is None:
            pos = nx.spring_layout(self.graph_weight)
            nx.draw(self.graph_weight, pos, with_labels=True)
            labels = nx.get_edge_attributes(self.graph_weight, 'weight')
            nx.draw_networkx_edge_labels(self.graph_weight, pos, edge_labels=labels)
            plt.savefig(name)
        else:
            pos = nx.spring_layout(self.graph)
            nx.draw(self.graph, pos, with_labels=True)
            plt.savefig(name)


if __name__ == '__main__':
    graph = GraphDict()
    data = [
        {
            "source": 'Node 1',
            "target": 'Node 3'
        },
        {
            "source": 'Node 2',
            "target": 'Node 3'
        },
        {
            "source": 'Node 2',
            "target": 'Node 4'
        },
        {
            "source": 'Node 1',
            "target": 'Node 4'
        }]
    data_weight = [
        {
            "source": 'Node 1',
            "target": 'Node 3',
            "weight": 3
        },
        {
            "source": 'Node 2',
            "target": 'Node 3',
            "weight": 3
        },
        {
            "source": 'Node 2',
            "target": 'Node 4',
            "weight": 3
        },
        {
            "source": 'Node 1',
            "target": 'Node 4',
            "weight": 3
        }]
    # graph.dict_to_graph(data)
    # graph.to_png("有向图的导出")
    graph.dict_to_graph_weight(data_weight)
    graph.to_png("权重")
    v = graph.graph_to_dict()
    print(v)

image-20230702110304161

继续努力,终成大器;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-Bash的基本特性

Linux-Bash的特性应用: 按命令展开: {} 花括号是Bash支持的一种特殊符号,可以简单的理解为小学时学的乘法结合率。 例如: echo {1..10} 1 2 3 4 5 6 7 8 9 101…10 表示1到10,则整个命令可以理解为echo 1 echo 2 ec…

MFC多文档绘制不同图形

VC6新建一个多文档项目;根据窗口标题的最后数字,绘制不同图形; void CPrdView::OnDraw(CDC* pDC) {CPrdDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1 pDoc->GetTitle();CPoin…

[abc周赛复盘] AtCoder Beginner Contest 308 20230701

[abc周赛复盘] AtCoder Beginner Contest 308 20230701 总结A - New Scheme1. 题目描述2. 思路分析3. 代码实现 B - Default Price1. 题目描述2. 思路分析3. 代码实现 C - Standings1. 题目描述2. 思路分析3. 代码实现 D - Snuke Maze1. 题目描述2. 思路分析3. 代码实现 E - M…

Apache Doris (十四) :聚合模型的局限性、模型选择建议及列定义建议

目录 1. 聚合模型的局限性 2.数据模型的选择建议 2.1 Aggregate数据模型选择 ​​​​​​​​​​​​​​2.2 Unique数据模型选择 ​​​​​​​​​​​​​​2.3 Duplicate数据模型选择 ​​​​​​​3. 列定义建议 进入正文之前,欢迎订阅专题、对博文点…

天津大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 天津大学(B)考研难度(☆☆☆☆) 天津大学计算机考研主要招生学院在智能与计算学部、佐治亚理工深圳学院、新媒体与传播学院。招生学院较多,目前均已出拟录取…

时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解 部分源码 %----------------------

HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境

一、目的 在之前的博客《HPM6750系列--第二篇 搭建Ubuntu开发环境》、《HPM6750系列--第三篇 搭建MACOS编译和调试环境》我们介绍了基于命令行的编译调试过程,整个过程稍微有些繁琐可能有些小伙伴不太习惯,那么本篇就介绍一下在Visual Studio Code下的开…

【Linux系统编程】shell的感性理解

文章目录 1. shell是什么?它有什么作用?2. 通过一个故事感性理解shell的运行机制开端发展波澜渐起(正常命令的处理)故事角色与处理过程中各部分的映射走向高潮(非法请求的处理)shell 存在的意义结尾 1. she…

Leetcode-每日一题【142.环形链表Ⅱ】

题目 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部…

每天一点Python——day45

#第四十五天 #字典元素的特点: #例:字典中的所有元素都是一个key-value对【键值对】,key不允许重复,value可以重复 a{name:张三,name:李四} print(a) #只会输出李四,因为键不允许重复,否则会出现值覆盖的情…

QMenu代码生成器

共4种选项: 文本:输入父对象名,文本即可 文本图标:输入父对象名,文本,图标 文本图标菜单:输入父对象名,子对象名,文本,图标 文本菜单:输入父对象名…

14 | count(*)这么慢,我该怎么办?

一下内容出自《MySQL 实战 45 讲》 14 | count(*)这么慢,我该怎么办? count(*) 的实现方式 不同的 MySQL 引擎中,count(*) 有不同的实现方式。 MyISAM 引擎把一个表的总行数存在了磁盘上,执行 count(*) 的时候会直接返回这个数…

斯坦福大学吴佳俊:通过自然监督编码理解视觉世界

导读 在智源大会的生成模型论坛上,斯坦福大学助理教授吴佳俊带来了精彩的演讲 “通过自然监督编码理解视觉世界”(Understanding the Visual World Through Naturally Supervised Code)。此次演讲从二维图像拓展到三维世界,从人类…

linux高并发网络编程开发(xml json)16_xml和Json相关api及文件解析制作

pdf详细版 01 学习目标 xml xml基础语法和规范C程序中如何使用xml开源库借助开源库,在C程序中生成xml文件已知一个xml文件,如何借助开源库解析xml文件数据 Json json的基础语法和规范C程序中如何使用json开源库 - cjson使用cjson生成json文件已知一个json文件,使用cjson库解析…

列存储、行存储

一、定义 1.1定义 Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析、数据挖掘等查询密集型应用。列存储,缩写为DSM,相对于NSM(N-ary storage model),其主要区别在于: DSM将所有记录中相同字段的数据聚…

【AUTOSAR】BMS开发实际项目讲解(二十三)----电池管理系统高压互锁保护

高压互锁保护 关联的系统需求 TSR-BMS-6101、TSR-BMS-6102、TSR-BMS-6103、TSR-BMS-6104、TSR-BMS-6105、TSR-BMS-6106、TSR-BMS-6107、TSR-BMS-6108、TSR-BMS-6109、TSR-BMS-6110、TSR-BMS-6111; TSR-BMS-6201; TSR-BMS-6301; TSR-BMS-S101、TSR-BMS-S102、TSR-BMS-S103、TS…

AutoSAR系列讲解(入门篇)4.3-BSW的Communication功能

一、架构与术语解释 BSW中以后每一节我都会放上一张模块图,所以就先上图: 由于汽车上一般都使用CAN总线,图中的bus大家可以就当成CAN来看待,如果使用的是LIN或者其他的,也相应的换成其总线看待就行。后续在实践篇中将会…

你需要了解的 50 个 ChatGPT 统计数据和事实

Rest assured that with the ChatGPT statistics you’re about to read, you’ll confirm that the popular chatbot from OpenAI is just the beginning of something bigger. Since its launch in November 2022, ChatGPT has broken unexpected records. For example, it r…

数据结构之串

1.串的基本概念 • 一个串是由n(n≥0)个字符组成的有限序列,记为s“s0s1 ⋯ sn-1”,其 中,s是串名,双引号括起来的字符序列s0s1 ⋯ sn-1是串值。 • 一个字符在串中的位置称为该字符在串中的序号&#xff…

微搭低代码实现表单打印功能

目录 1 引入第三方库2 搭建页面3 实现打印4 实现效果总结 在我们的日常开发场景中,表单打印是一个比较常见的场景,微搭本身不带打印功能,我们需要借助一个第三方的库来实现打印。 1 引入第三方库 在微搭中如果需要引入第三方库的&#xff0…