如何基于给定DataFrame为Plotly桑基图准备数据?
用Pandas数据绘制Plotly桑基图的数据准备方法
1. 明确桑基图数据要求
Plotly桑基图依赖两类核心数据:
- 节点(nodes):所有出现在层级中的唯一标识,每个节点对应一个专属索引。
- 链接(links):节点间的关联关系,包含源节点索引、目标节点索引,以及代表流量的数值。
你的需求是构建Id → ColA → ColB → ColC的层级关系,以下是具体实现步骤:
2. 导入依赖库
import pandas as pd import plotly.graph_objects as go
3. 定义原始数据
df = pd.DataFrame({'Id': [1, 2, 3, 4], 'ColA': [30, 20, 20,30], 'ColB':[50, 20, 30,70], 'ColC':[70, 30, 20,80]})
4. 准备节点数据
收集所有层级的唯一节点,并创建节点与索引的映射:
# 收集所有节点(Id + 各列数值),转字符串避免数值类型冲突 nodes = [] nodes.extend(df['Id'].astype(str).tolist()) for col in ['ColA', 'ColB', 'ColC']: nodes.extend(df[col].astype(str).tolist()) # 去重并保留首次出现顺序 nodes = list(dict.fromkeys(nodes)) # 创建节点到索引的映射字典 node_map = {node: idx for idx, node in enumerate(nodes)}
5. 准备链接数据
提供两种方式,可根据需求选择:
方式1:保留每条原始路径(流量为1)
遍历每一行数据,依次建立相邻列的链接:
links = {'source': [], 'target': [], 'value': []} for _, row in df.iterrows(): # Id → ColA links['source'].append(node_map[str(row['Id'])]) links['target'].append(node_map[str(row['ColA'])]) links['value'].append(1) # ColA → ColB links['source'].append(node_map[str(row['ColA'])]) links['target'].append(node_map[str(row['ColB'])]) links['value'].append(1) # ColB → ColC links['source'].append(node_map[str(row['ColB'])]) links['target'].append(node_map[str(row['ColC'])]) links['value'].append(1)
方式2:聚合相同路径的流量(流量为出现次数)
如果需要体现相同节点对的出现频次,用分组统计生成链接:
links = {'source': [], 'target': [], 'value': []} # 统计Id到ColA的流量 for _, row in df.groupby(['Id', 'ColA']).size().reset_index(name='count').iterrows(): links['source'].append(node_map[str(row['Id'])]) links['target'].append(node_map[str(row['ColA'])]) links['value'].append(row['count']) # 统计ColA到ColB的流量 for _, row in df.groupby(['ColA', 'ColB']).size().reset_index(name='count').iterrows(): links['source'].append(node_map[str(row['ColA'])]) links['target'].append(node_map[str(row['ColB'])]) links['value'].append(row['count']) # 统计ColB到ColC的流量 for _, row in df.groupby(['ColB', 'ColC']).size().reset_index(name='count').iterrows(): links['source'].append(node_map[str(row['ColB'])]) links['target'].append(node_map[str(row['ColC'])]) links['value'].append(row['count'])
6. 绘制桑基图
fig = go.Figure(data=[go.Sankey( node = dict( pad = 15, thickness = 20, line = dict(color = "black", width = 0.5), label = nodes # 节点显示标签 ), link = dict( source = links['source'], target = links['target'], value = links['value'] ) )]) fig.update_layout(title_text="Id到各列数值的桑基图", font_size=10) fig.show()
内容的提问来源于stack exchange,提问作者Uqhah
相关产品推荐
相关产品推荐

