本期所用数据集,空手道俱乐部关系数据集:
- 数据集中共有34个节点,每个节点代表俱乐部中的一名成员
- 数据集中共有78条边,每条边表示两名成员之间的友谊关系或社交联系
- 常见数据集格式为GML和TXT格式,还可能包含其他格式的文件,如邻接矩阵、权值矩阵、net格式等
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
G = nx.karate_club_graph() # 空手道俱乐部图。
#调用 nx.karate_club_graph() 时,返回一个NetworkX图对象(Graph object)
#该对象包含了上述的节点和边信息。这个图对象可以使用NetworkX提供的各种函数进行进一步的分析和可视化
pos = nx.spring_layout(G,seed=1)
#设置节点位置。seed随机种子决定了每次运行后节点分布确定
#pos 是一个字典,其中键是图中的节点,值是该节点在二维空间中的位置(通常是x和y坐标)
#这些位置是由Spring布局算法计算得出
plt.figure(figsize = (14,8))
nx.draw_networkx(G, pos, node_color = 'green',edge_color = 'red')
plt.savefig('全图.svg')
度分析(确定关系中心)
连通性:
- 用于描述“图的节点如何通过边相连”;
- 连通图中任意两点间都有路径相连;非连通图存在至少一对节点间无路径相连
- 连通分量是无向图中最大的连通子图
- 有向图的强连通意味着任意两点间存在双向路径;弱连通则至少通过将所有边视为无向边可实现连通
-
桥是图中 移除后 会 增加连通分量数量 的边,局部桥是除非两端直接相连外,不属于任何其他更小的循环的边
度分析:使用图的节点度数帮助分析图的连通性
1、节点标签-度数bar图
degree_sequence = sorted((d for n, d in G.degree()),
reverse=True)
# 度数从大到小排序(n为序号,d为度数,但是只取度数d)——返回结果为数组形式
dmax = max(degree_sequence) #取度数的最大值
dict_degree = dict(G.degree()) #将结果转为字典(节点标签:度数)
pd.DataFrame(list(dict_degree.items()), columns=['Key', 'Values']) #字典转换为列表再转换为DataFrame,列名'节点标签Key', 度数值'Values'
# 每个节点的具体度数
plt.bar(dict_degree.keys(),dict_degree.values())
plt.xlabel('Node label')
plt.ylabel('Degree')
plt.savefig('节点度数bar chart.svg')
2、度数等级图
set(degree_sequence) #将sorted排序后的数组转换为集合set格式
fig, ax = plt.subplots(figsize = (14,8))
ax.plot(degree_sequence, "g-", marker="o")
ax.set_ylabel("Degree")
ax.set_xlabel("Rank")
ax.set_xlim(0,34)
ax.set_ylim(0,17)
plt.savefig('度数等级图.svg')
3、度数直方图(度数-该度数频数)
fig, ax = plt.subplots(figsize = (14,8))
ax.bar(*np.unique(degree_sequence, return_counts=True))
ax.set_xlabel("Degree")
ax.set_ylabel("Number of Nodes")
plt.savefig('度数直方图.svg')
4、根据度数渲染颜色
试着绘制最大连通分量:
#这次不用空手道俱乐部图数据了,用随机图
G = nx.gnp_random_graph(100, 0.02, seed=1) # 创建随机图对象
#plt.figure(figsize = (14,9))
#pos = nx.spring_layout(G, seed = 8)
#nx.draw_networkx(G, pos,
with_labels = False,
node_size=20, node_color = 'green')
#plt.savefig('全图.svg') #绘制全图
Gcc = G.subgraph(sorted(nx.connected_components(G),
key=len, reverse=True)[0]) #连通分量(节点数最多)
pos_Gcc = {k: pos[k] for k in list(Gcc.nodes())}
# 取出子图节点坐标。返回一个字典
plt.figure(figsize = (14,9))
nx.draw_networkx(Gcc, pos_Gcc,
with_labels = False,
node_size=50, node_color = 'red')
plt.savefig('最大连通分量.svg')
根据度数渲染节点颜色:
#前处理:类比上面俱乐部数据处理方法
degree_sequence = sorted((d for n, d in G.degree()),
reverse=True) # 度数大小排序
dmax = max(degree_sequence)
dict_degree = dict(G.degree()) # 将结果转为字典
set(degree_sequence)
# 自定义函数,过滤dict:从字典中提取 value 满足特定要求的部分,结果还是一个字典
def filter_value(dict_, unique):
newDict = {}
for (key, value) in dict_.items():
if value == unique:
newDict[key] = value
return newDict
unique_deg = set(degree_sequence)
# 取出节点度数独特值:用集合运算提取节点度数的独特值
colors = plt.cm.RdYlBu_r(np.linspace(0, 1, len(unique_deg)))
# 独特值的颜色映射:节点度数独特值的颜色映射;度数高用暖色调,度数低用冷色调
plt.figure(figsize = (14,9))
nx.draw_networkx_edges(G, pos)
# 绘制图的边
# 分别绘制不同度数节点:根据节点度数大小分批绘制节点
for deg_i, color_i in zip(unique_deg,colors):
dict_i = filter_value(dict_degree,deg_i)
nx.draw_networkx_nodes(G, pos,
nodelist = list(dict_i.keys()),
node_size=40,
node_color = color_i)
plt.savefig('根据度数大小渲染节点.svg')