You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中创建带无数值子节点的自定义分解树图表?

定制化分解树图表实现方案(类Power BI)

需求说明

  • 实现层级化分解树图表,匹配Power BI分解树核心逻辑
  • 支持仅含标题、无关联数值的「Sub-child」层级节点
  • 节点样式为方形/矩形(替代Power BI默认的细水平条)

现有数据

import pandas as pd
df = pd.DataFrame({'Parent': ['Parent', 'Parent', 'Parent', 'Parent', 'Parent', 'Parent',
                              'Parent', 'Parent', 'Parent', 'Parent', 'Parent', 'Parent'],
                   'Child': ['Child 1', 'Child 1', 'Child 1', 'Child 1', 'Child2', 'Child2',
                             'Child2', 'Child2', 'Child3', 'Child3', 'Child3', 'Child3'],
                   'Child-Values': ['40%', '40%', '40%', '40%', '35%', '35%', '35%', '35%', '25%',
                                    '25%', '25%', '25%'],
                   'Sub-Child': ['Sub-child 1', 'Sub-child 1', 'Sub-child 2', 'Sub-child 2',
                                'Sub-child 1', 'Sub-child 1', 'Sub-child 2', 'Sub-child 2',
                                'Sub-child 1', 'Sub-child 1', 'Sub-child 2', 'Sub-child 2'],
                   'Sub-Sub-Child': ['A1', 'A2', 'B1', 'B2', 'A1', 'A2', 'B1', 'B2', 'A1', 'A2',
                                    'B1', 'B2'],
                   'Sub-Sub-Child-Values': ['40%', '60%', '25%', '75%', '80%', '20%', '45%',
                                            '55%', '35%', '65%', '30%', '70%']})

问题背景

尝试过pandas、Plotly等库未找到适配方案,使用treeplotter库调用create_tree_diagram时出现参数缺失错误。


解决方案

方案1:修复treeplotter参数问题

treeplotter的create_tree_diagram需要明确的树状结构映射,先整理数据为父-子节点字典,再传递必要参数:

from treeplotter import Tree

# 去重并构建层级节点映射
parent_child_map = {}
# 顶级节点
parent_child_map['Parent'] = []

# 处理Child层级(带数值)
for child, val in df[['Child', 'Child-Values']].drop_duplicates().values:
    child_node = f"{child} ({val})"
    parent_child_map['Parent'].append(child_node)
    parent_child_map[child_node] = []

# 处理Sub-Child层级(无数值)
for child, sub_child in df[['Child', 'Sub-Child']].drop_duplicates().values:
    parent_node = f"{child} ({df[df['Child']==child]['Child-Values'].iloc[0]})"
    parent_child_map[parent_node].append(sub_child)
    parent_child_map[sub_child] = []

# 处理Sub-Sub-Child层级(带数值)
for sub_child, sub_sub_child, val in df[['Sub-Child', 'Sub-Sub-Child', 'Sub-Sub-Child-Values']].drop_duplicates().values:
    child_node = f"{sub_sub_child} ({val})"
    parent_child_map[sub_child].append(child_node)

# 生成树状图
tree = Tree()
tree.create_tree_diagram(
    root_name='Parent',
    parent_child_dict=parent_child_map,
    node_shape='square',  # 指定方形节点
    node_size=2200,
    font_size=10
)

方案2:自定义实现(NetworkX + Matplotlib)

如果treeplotter仍有兼容问题,用NetworkX构建树结构,Matplotlib完全自定义节点样式:

import networkx as nx
import matplotlib.pyplot as plt

# 构建有向树图
G = nx.DiGraph()

# 添加节点与边
# 顶级节点
G.add_node('Parent', label='Parent')
# Child层级
for child, val in df[['Child', 'Child-Values']].drop_duplicates().values:
    node_label = f"{child}\n({val})"
    G.add_node(child, label=node_label)
    G.add_edge('Parent', child)
# Sub-Child层级(无数值)
for child, sub_child in df[['Child', 'Sub-Child']].drop_duplicates().values:
    G.add_node(sub_child, label=sub_child)
    G.add_edge(child, sub_child)
# Sub-Sub-Child层级
for sub_child, sub_sub_child, val in df[['Sub-Child', 'Sub-Sub-Child', 'Sub-Sub-Child-Values']].drop_duplicates().values:
    node_label = f"{sub_sub_child}\n({val})"
    G.add_node(sub_sub_child, label=node_label)
    G.add_edge(sub_child, sub_sub_child)

# 层级布局
pos = nx.nx_agraph.graphviz_layout(G, prog='dot')

# 绘制图表
plt.figure(figsize=(14, 9))
nx.draw_networkx_edges(G, pos, edge_color='gray', arrowstyle='-')
# 方形节点
nx.draw_networkx_nodes(G, pos, node_shape='s', node_size=3500, node_color='#e6f2ff')
# 节点标签
nx.draw_networkx_labels(G, pos, labels=nx.get_node_attributes(G, 'label'), font_size=9)

plt.box(False)
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Prem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:47:34