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")