mesa/绘制度.py

116 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pickle
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
# 1. 读取并处理数据
bom_nodes = pd.read_csv('input_data/input_product_data/BomNodes.csv')
bom_nodes['Code'] = bom_nodes['Code'].astype(str)
bom_nodes.set_index('Index', inplace=True)
bom_cate_net = pd.read_csv('input_data/input_product_data/合成结点.csv')
# 2. 构建图结构
g_bom = nx.from_pandas_edgelist(bom_cate_net, source='UPID', target='ID', create_using=nx.MultiDiGraph())
# 填充每一个结点的具体内容
bom_labels_dict = {}
for index in g_bom.nodes:
try:
bom_labels_dict[index] = bom_nodes.loc[index].to_dict()
except KeyError:
print(f"节点 {index} 不存在于 bom_nodes 中")
# 分配属性给每一个结点
nx.set_node_attributes(g_bom, bom_labels_dict)
# 3. 计算每个节点的度数
degrees = dict(g_bom.degree()) # 总度数(适用于有向图)
# 4. 统计每个度数的节点数量
degree_counts = {}
for degree in degrees.values():
if degree in degree_counts:
degree_counts[degree] += 1
else:
degree_counts[degree] = 1
# 转换为排序后的列表(横坐标:度数,纵坐标:节点数)
sorted_degrees = sorted(degree_counts.keys())
sorted_counts = [degree_counts[d] for d in sorted_degrees]
# 5. 绘制度分布图
plt.figure(figsize=(12, 8)) # 增大画布尺寸
bars = plt.bar(sorted_degrees, sorted_counts, width=0.8)
plt.title('Degree Distribution In Industrial Chain', fontsize=16)
plt.xlabel('Degree', fontsize=14)
plt.ylabel('Number of Nodes', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)
plt.xticks(rotation=45) # 如果度数较多可以旋转x轴标签
plt.tight_layout() # 防止标签重叠
# 6. 在每个柱子上方标注数值
for bar in bars:
height = bar.get_height()
plt.text(
bar.get_x() + bar.get_width() / 2, # x坐标柱子中心
height + max(sorted_counts) * 0.02, # y坐标柱子顶部上方留出空间
f'{int(height)}', # 显示数值(转换为整数)
ha='center', # 水平居中
va='bottom', # 垂直底部对齐
fontsize=10, # 字体大小
color='black' # 字体颜色
)
# 7. 保存超高清图片300 DPI
output_path = "degree_distribution_with_labels.png" # 输出文件名
plt.savefig(output_path, dpi=500, bbox_inches='tight') # dpi=300 确保高分辨率
print(f"图片已保存至: {output_path}")
# 1. 加载企业网络数据
with open("firm_network.pkl", 'rb') as f:
G_firm = pickle.load(f)
print(f"Successfully loaded cached data from firm_network.pkl")
# 2. 计算企业网络的度分布
degrees_firm = dict(G_firm.degree()) # 总度数
degree_counts_firm = {}
for degree in degrees_firm.values():
if degree in degree_counts_firm:
degree_counts_firm[degree] += 1
else:
degree_counts_firm[degree] = 1
# 转换为排序后的列表
sorted_degrees_firm = sorted(degree_counts_firm.keys())
sorted_counts_firm = [degree_counts_firm[d] for d in sorted_degrees_firm]
# 3. 绘制企业网络的度分布图
plt.figure(figsize=(12, 6)) # 单独画布尺寸
plt.bar(sorted_degrees_firm, sorted_counts_firm, width=0.8)
plt.title('Degree Distribution of Firm Network', fontsize=16)
plt.xlabel('Degree (Number of Connections)', fontsize=14)
plt.ylabel('Number of Firms', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)
plt.xticks(rotation=45)
plt.tight_layout()
# 在柱子上方标注数值
for bar in plt.gca().containers[0]: # 获取当前图中的柱子对象
height = bar.get_height()
plt.text(
bar.get_x() + bar.get_width() / 2,
height + max(sorted_counts_firm) * 0.02,
f'{int(height)}',
ha='center',
va='bottom',
fontsize=10,
color='black'
)
# 保存图片
plt.savefig("degree_distribution_firm.png", dpi=500, bbox_inches='tight')
print("企业度分布图已保存至: degree_distribution_firm.png")