硬核教程,利用 Python 搞定精美网络图

硬核教程,

利用 Python 搞定精美网络图!

一、NetworkX 概述

NetworkX 是一个用 Python 语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。

Networkx 支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富。主要用于创造、操作复杂网络,以及学习复杂网络的结构、动力学及其功能。用于分析网络结构,建立网络模型,设计新的网络算法,绘制网络等等。

PS:本文所使用的数据源以及代码文件,可以在文末获取

二、NetworkX 的安装

 
  1. pip install networkx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

三、NetworkX 基础知识

1. 创建图

可以利用 networkx 创建四种图: Graph 、DiGraph、MultiGraph、MultiDiGraph,分别为无多重边无向图、无多重边有向图、有多重边无向图、有多重边有向图。

 
  1. import network as nx

  2. G = nx.Graph()

  3. G = nx.DiGraph()

  4. G = nx.MultiGraph()

  5. G = nx.MultiDiGraph()

2. 网络图的加点和加边

 
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3.  

  4. G = nx.DiGraph()

  5. G.add_node('z') # 添加节点z

  6. G.add_nodes_from([1, 2, 3]) # 添加节点 1 2 3

  7. G.add_edge('x', 'y') # 添加边 起点为x 终点为y

  8. G.add_edges_from([(1, 2), (1, 3), (2, 3)]) # 添加多条边

  9.  

  10. # 网络图绘制与显示

  11. nx.draw(G, with_labels=True)

  12. plt.show()

运行效果如下:

图片

为了让网络图更美观可以调节 nx.draw() 方法里的参数

 
  1. nx.draw(G, pos=nx.random_layout(G), node_color = 'b', edge_color = 'r', with_labels = True, font_size =18, node_size =20)

  • G:待绘制的网络图G

  • node_size:指定节点的尺寸大小(默认是300)

  • node_color: 指定节点的颜色 (可以用字符串简单标识颜色,例如'r'为红色,'g'为绿色这样)

  • node_shape: 节点的形状(默认是圆形,用字符串'o'标识)

  • alpha: 透明度 (默认是1.0,不透明,0为完全透明)

  • width: 边的宽度 (默认为1.0)

  • edge_color: 边的颜色(默认为黑色)

  • style: 边的样式(默认为实现,可选: solid | dashed | dotted | dashdot

  • with_labels:节点是否带标签

  • font_size: 节点标签字体大小

  • font_color: 节点标签字体颜色(默认为黑色)

3. 运用布局

circular_layout:节点在一个圆环上均匀分布 

random_layout:节点随机分布 

shell_layout:节点在同心圆上分布 

spring_layout:用 Fruchterman-Reingold 算法排列节点(样子类似多中心放射状) 

spectral_layout:根据图的拉普拉斯特征向量排列节点

绘制网络图实例如下:

 
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3.  

  4. # 初始化一个有向图对象

  5. DG = nx.DiGraph()

  6. DG.add_node('X')

  7. # 添加节点 传入列表

  8. DG.add_nodes_from(['A', 'B', 'C', 'D', 'E'])

  9. print(f'输出图的全部节点:{DG.nodes}')

  10. print(f'输出节点的数量:{DG.number_of_nodes()}')

  11. # 添加边 传入列表 列表里每个元素是一个元组 元组里表示一个点指向另一个点的边

  12. DG.add_edges_from([('A', 'B'), ('A', 'C'), ('A', 'D'), ('D', 'A'), ('E', 'A'), ('E', 'D')])

  13. DG.add_edge('X', 'C')

  14. print(f'输出图的全部边:{DG.edges}')

  15. print(f'输出边的数量:{DG.number_of_edges()}')

  16. # 可自定义节点颜色

  17. colors = ['pink', 'blue', 'green', 'yellow', 'red', 'brown']

  18. # 运用布局

  19. pos = nx.circular_layout(DG)

  20. # 绘制网络图

  21. nx.draw(DG, pos=pos, with_labels=True, node_size=200, width=0.6, node_color=colors)

  22. # 展示图片

  23. plt.show()

运行效果如下:

 
  1. 输出图的全部节点:['X', 'A', 'B', 'C', 'D', 'E']

  2. 输出节点的数量:6

  3. 输出图的全部边:[('X', 'C'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('D', 'A'), ('E', 'A'), ('E', 'D')]

  4. 输出边的数量:7

图片

四、利用 NetworkX 实现关联类分析

利用 soccer.csv 中的数据,使用 Python 的 NetworkX 包按要求进行绘图。

图片

1. 提取数据

统计不同俱乐部(Club)的球员数量,从球员最多的五个俱乐部抽取 50 名球员信息(球员数量最多的俱乐部抽取 30 名,剩下 4 个俱乐部各抽取 5 名)构成新的 DataFrame,打印其 info()。

 
  1. import pandas as pd

  2.  

  3. df = pd.read_csv('soccer.csv', encoding='gbk')

  4. data = df['Club'].value_counts()

  5. # 球员人数最多的5个俱乐部

  6. clubs = list(data.index[:5])

  7.  

  8. # 球员数量最多的俱乐部抽取30名

  9. df1 = df[df['Club'] == clubs[0]].sample(30, axis=0)

  10. # 剩下4个俱乐部各抽取5名

  11. df2 = df[df['Club'] == clubs[1]].sample(5, axis=0)

  12. df3 = df[df['Club'] == clubs[2]].sample(5, axis=0)

  13. df4 = df[df['Club'] == clubs[3]].sample(5, axis=0)

  14. df5 = df[df['Club'] == clubs[4]].sample(5, axis=0)

  15.  

  16. # 合并多个DataFrame

  17. result = pd.concat([df1, df2, df3, df4, df5], axis=0, ignore_index=True)

  18. # 打乱DataFrame顺序

  19. new_result = result.sample(frac=1).reset_index(drop=True)

  20. # new_result.info()

  21. # 抽样的数据保存到excel

  22. new_result.to_excel('samples.xlsx')

Jupyter Notebook 环境中读取 samples.xlsx,打印其 info(),结果如下:领取免费教程及资料+v:boyin7988  备注Python即可

 
  1. import pandas as pd

  2.  

  3. df = pd.read_excel('samples.xlsx')

  4. df.info()

图片

2. 画网络图

在提取出的数据的基础上,通过判断球员是否属于同一俱乐部,绘出随机分布网络图、Fruchterman-Reingold 算法排列节点网络图与同心圆分布网络图。尽可能让网络图美观,如为属于同一俱乐部的节点设置相同的颜色。

将每个球员当作网络图中一个节点,计算节点之间的连通关系,同属一个俱乐部则连通。

 
  1. import pandas as pd

  2.  

  3. df = pd.read_excel('samples.xlsx')

  4. df = df.loc[::, ['Name', 'Club']]

  5. print(df['Club'].value_counts())

  6. datas = df.values.tolist()

  7. name = [datas[i][0] for i in range(len(datas))]

  8. nodes = [str(i) for i in range(len(datas))]

  9. club = [datas[i][1] for i in range(len(datas))]

  10. # print(nodes)

  11. df = pd.DataFrame({'姓名': name, '节点编号': nodes, '所属俱乐部': club})

  12. df.to_csv('nodes_info.csv')

  13. with open('record.txt', 'w') as f:

  14. for i in range(len(nodes)):

  15. for j in range(i, len(nodes) - 1):

  16. if datas[i][1] == datas[j+1][1]: # 属于同一俱乐部

  17. f.write(f'{nodes[i]}-{nodes[j + 1]}-{datas[i][1]}'+ '\n')

(1) 随机分布网络图

 
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3. import pandas as pd

  4. from collections importCounter

  5.  

  6. df = pd.read_csv('nodes_info.csv')['所属俱乐部']

  7. items = df.values

  8. print(Counter(items))

  9. node_colors = []

  10. # 5个俱乐部 属于同一个俱乐部的节点设置相同颜色

  11. for item in items:

  12. if item == 'Free Agents':

  13. node_colors.append('red')

  14. elif item == 'Real Madrid':

  15. node_colors.append('yellow')

  16. elif item == 'Chelsea':

  17. node_colors.append('blue')

  18. elif item == 'FC Barcelona':

  19. node_colors.append('green')

  20. elif item == 'Manchester Utd':

  21. node_colors.append('pink')

  22.  

  23.  

  24. DG = nx.MultiGraph()

  25. DG.add_nodes_from([str(i) for i in range(0, 50)])

  26. DG.nodes()

  27.  

  28. with open('record.txt', 'r') as f:

  29. con = f.read().split('\n')

  30.  

  31. edges_list = []

  32. for i in con[:-1]:

  33. edges_list.append(tuple(i.split('-')[:2]))

  34.  

  35. print(edges_list)

  36. DG.add_edges_from(edges_list)

  37.  

  38. # 运用布局

  39. pos = nx.random_layout(DG) # 节点随机分布

  40. # 绘制网络图

  41. nx.draw(DG, pos, with_labels=True, node_size=200, width=0.6, node_color=node_colors)

  42. # 显示图片

  43. plt.show()

运行效果如下:

图片

(2) Fruchterman-Reingold 算法排列节点网络图

 
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3. import pandas as pd

  4. from collections importCounter

  5.  

  6. df = pd.read_csv('nodes_info.csv')['所属俱乐部']

  7. items = df.values

  8. print(Counter(items))

  9. node_colors = []

  10. # 5个俱乐部 属于同一个俱乐部的节点设置相同颜色

  11. for item in items:

  12. if item == 'Free Agents':

  13. node_colors.append('red')

  14. elif item == 'Real Madrid':

  15. node_colors.append('yellow')

  16. elif item == 'Chelsea':

  17. node_colors.append('blue')

  18. elif item == 'FC Barcelona':

  19. node_colors.append('green')

  20. elif item == 'Manchester Utd':

  21. node_colors.append('pink')

  22.  

  23. DG = nx.MultiGraph()

  24. DG.add_nodes_from([str(i) for i in range(0, 50)])

  25. DG.nodes()

  26.  

  27. with open('record.txt', 'r') as f:

  28. con = f.read().split('\n')

  29.  

  30. edges_list = []

  31. for i in con[:-1]:

  32. edges_list.append(tuple(i.split('-')[:2]))

  33.  

  34. print(edges_list)

  35. DG.add_edges_from(edges_list)

  36.  

  37. # 运用布局

  38. pos = nx.spring_layout(DG) # 用Fruchterman-Reingold算法排列节点(样子类似多中心放射状)

  39. # 绘制网络图

  40. nx.draw(DG, pos, node_size=10, width=0.6, node_color=node_colors)

  41. # 显示图片

  42. plt.show()

运行效果如下:

图片

(3) 同心圆分布网络图领取免费教程及资料+v:boyin7988  备注Python即可

 
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3. import pandas as pd

  4. from collections importCounter

  5.  

  6. df = pd.read_csv('nodes_info.csv')['所属俱乐部']

  7. items = df.values

  8. print(Counter(items))

  9. node_colors = []

  10. # 5个俱乐部 属于同一个俱乐部的节点设置相同颜色

  11. for item in items:

  12. if item == 'Free Agents':

  13. node_colors.append('red')

  14. elif item == 'Real Madrid':

  15. node_colors.append('yellow')

  16. elif item == 'Chelsea':

  17. node_colors.append('blue')

  18. elif item == 'FC Barcelona':

  19. node_colors.append('green')

  20. elif item == 'Manchester Utd':

  21. node_colors.append('pink')

  22.  

  23. DG = nx.MultiGraph()

  24. DG.add_nodes_from([str(i) for i in range(0, 50)])

  25. DG.nodes()

  26.  

  27. with open('record.txt', 'r') as f:

  28. con = f.read().split('\n')

  29.  

  30. edges_list = []

  31. for i in con[:-1]:

  32. edges_list.append(tuple(i.split('-')[:2]))

  33.  

  34. print(edges_list)

  35. DG.add_edges_from(edges_list)

  36.  

  37. # 运用布局

  38. pos = nx.shell_layout(DG) # 节点在同心圆上分布

  39. # 绘制网络图

  40. nx.draw(DG, pos, with_labels=True, node_size=200, width=0.6, node_color=node_colors)

  41. # 显示图片

  42. plt.show()

运行效果如下:

图片

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值