作者:叶庭云
编辑:Lemon
出品:Python数据之道
硬核教程,
利用 Python 搞定精美网络图!
NetworkX 是一个用 Python 语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。
Networkx 支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富。主要用于创造、操作复杂网络,以及学习复杂网络的结构、动力学及其功能。用于分析网络结构,建立网络模型,设计新的网络算法,绘制网络等等。
PS:本文所使用的数据源以及代码文件,可以在文末获取
可以利用 networkx 创建四种图: Graph 、DiGraph、MultiGraph、MultiDiGraph,分别为无多重边无向图、无多重边有向图、有多重边无向图、有多重边有向图。
import network as nx G = nx.Graph() G = nx.DiGraph() G = nx.MultiGraph() G = nx.MultiDiGraph()运行效果如下:
为了让网络图更美观可以调节 nx.draw() 方法里的参数
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: 节点标签字体颜色(默认为黑色)
circular_layout:节点在一个圆环上均匀分布
random_layout:节点随机分布
shell_layout:节点在同心圆上分布
spring_layout:用 Fruchterman-Reingold 算法排列节点(样子类似多中心放射状)
spectral_layout:根据图的拉普拉斯特征向量排列节点
绘制网络图实例如下:
import networkx as nx import matplotlib.pyplot as plt # 初始化一个有向图对象 DG = nx.DiGraph() DG.add_node('X') # 添加节点 传入列表 DG.add_nodes_from(['A', 'B', 'C', 'D', 'E']) print(f'输出图的全部节点:{DG.nodes}') print(f'输出节点的数量:{DG.number_of_nodes()}') # 添加边 传入列表 列表里每个元素是一个元组 元组里表示一个点指向另一个点的边 DG.add_edges_from([('A', 'B'), ('A', 'C'), ('A', 'D'), ('D', 'A'), ('E', 'A'), ('E', 'D')]) DG.add_edge('X', 'C') print(f'输出图的全部边:{DG.edges}') print(f'输出边的数量:{DG.number_of_edges()}') # 可自定义节点颜色 colors = ['pink', 'blue', 'green', 'yellow', 'red', 'brown'] # 运用布局 pos = nx.circular_layout(DG) # 绘制网络图 nx.draw(DG, pos=pos, with_labels=True, node_size=200, width=0.6, node_color=colors) # 展示图片 plt.show()运行效果如下:
输出图的全部节点:['X', 'A', 'B', 'C', 'D', 'E'] 输出节点的数量:6 输出图的全部边:[('X', 'C'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('D', 'A'), ('E', 'A'), ('E', 'D')] 输出边的数量:7利用 soccer.csv 中的数据,使用 Python 的 NetworkX 包按要求进行绘图。
统计不同俱乐部(Club)的球员数量,从球员最多的五个俱乐部抽取 50 名球员信息(球员数量最多的俱乐部抽取 30 名,剩下 4 个俱乐部各抽取 5 名)构成新的 DataFrame,打印其 info()。
import pandas as pd df = pd.read_csv('soccer.csv', encoding='gbk') data = df['Club'].value_counts() # 球员人数最多的5个俱乐部 clubs = list(data.index[:5]) # 球员数量最多的俱乐部抽取30名 df1 = df[df['Club'] == clubs[0]].sample(30, axis=0) # 剩下4个俱乐部各抽取5名 df2 = df[df['Club'] == clubs[1]].sample(5, axis=0) df3 = df[df['Club'] == clubs[2]].sample(5, axis=0) df4 = df[df['Club'] == clubs[3]].sample(5, axis=0) df5 = df[df['Club'] == clubs[4]].sample(5, axis=0) # 合并多个DataFrame result = pd.concat([df1, df2, df3, df4, df5], axis=0, ignore_index=True) # 打乱DataFrame顺序 new_result = result.sample(frac=1).reset_index(drop=True) # new_result.info() # 抽样的数据保存到excel new_result.to_excel('samples.xlsx')Jupyter Notebook 环境中读取 samples.xlsx,打印其 info(),结果如下:
import pandas as pd df = pd.read_excel('samples.xlsx') df.info()在提取出的数据的基础上,通过判断球员是否属于同一俱乐部,绘出随机分布网络图、Fruchterman-Reingold 算法排列节点网络图与同心圆分布网络图。尽可能让网络图美观,如为属于同一俱乐部的节点设置相同的颜色。
将每个球员当作网络图中一个节点,计算节点之间的连通关系,同属一个俱乐部则连通。
import pandas as pd df = pd.read_excel('samples.xlsx') df = df.loc[::, ['Name', 'Club']] print(df['Club'].value_counts()) datas = df.values.tolist() name = [datas[i][0] for i in range(len(datas))] nodes = [str(i) for i in range(len(datas))] club = [datas[i][1] for i in range(len(datas))] # print(nodes) df = pd.DataFrame({'姓名': name, '节点编号': nodes, '所属俱乐部': club}) df.to_csv('nodes_info.csv') with open('record.txt', 'w') as f: for i in range(len(nodes)): for j in range(i, len(nodes) - 1): if datas[i][1] == datas[j+1][1]: # 属于同一俱乐部 f.write(f'{nodes[i]}-{nodes[j + 1]}-{datas[i][1]}'+ '\n')运行效果如下:
运行效果如下:
运行效果如下:
作者简介
叶庭云
个人格言: 热爱可抵岁月漫长
博客: https://blog.csdn.net/fyfugoyfa/
---------End---------
“分享”和“在看”是更好的支持!