京公网安备 11010802034615号
经营许可证编号:京B2-20210330
在数据可视化领域,树状图(Tree Diagram)是呈现层级结构数据的核心工具——无论是电商商品分类、企业组织架构,还是数据挖掘中的决策树模型结果,都需要通过树状图将“父-子”关联关系直观化。matplotlib.pyplot(简称pyplot)作为Python最经典的可视化库,凭借灵活的参数配置和良好的兼容性,成为实现树状图的主流选择。本文将从技术本质、核心价值、实操步骤、进阶优化到业务落地,完整解析pyplot树状图的应用逻辑,附可直接运行的代码案例与场景适配方案。
要掌握pyplot树状图,需先明确其技术本质与核心特性——它并非单一“树状图函数”的直接调用,而是通过pyplot的基础绘图函数(如barh、plot)构建层级关系,实现“数据层级→视觉层级”的转化。
Pyplot树状图是基于matplotlib.pyplot库实现的层级数据可视化组件,核心是将“具有父子关联的结构化数据”(如“大类→中类→小类”的商品分类)转化为“横向/纵向分支结构”的图形,其中:
“节点”:代表层级中的一个数据单元(如“家电”“智能手机”);
“分支”:连接父节点与子节点的线条,体现关联关系;
“层级深度”:通过节点的缩进、位置或颜色区分(如一级节点左对齐,二级节点缩进20px)。
与专业树状图工具(如Graphviz)相比,pyplot的优势在于“无需额外依赖、可与Python数据生态(Pandas、NumPy)无缝衔接”,尤其适合需要嵌入数据分析流程的场景。
Pyplot本身没有专门的“tree”函数,树状图的实现本质是手动定义节点坐标,通过基础图形组合完成:
这种“基础函数组合”的特性,让pyplot树状图具备极高的灵活性——可按需定制节点样式、分支颜色、标签字体,完全适配业务可视化需求。
在Python可视化生态中,虽有NetworkX、Plotly等库可实现树状图,但pyplot仍占据重要地位,核心价值体现在三个维度:
Pyplot树状图可直接读取Pandas DataFrame、NumPy数组等常用数据格式,无需复杂的数据转换。例如,电商商品分类数据(存于DataFrame)可直接提取“父分类、子分类、数值”字段,用于树状图绘制,避免跨工具数据传递的麻烦。
企业级可视化常需符合品牌规范(如特定颜色、字体),pyplot支持精细化样式控制:节点颜色可关联业务指标(如销量高的分类用红色,低的用蓝色),标签字体可匹配品牌字体,分支线条可调整粗细与透明度,远超Excel、Tableau等工具的固定样式。
Pyplot是matplotlib的核心模块,几乎是Python数据分析环境的“标配”,无需额外安装库。在数据挖掘项目中,可直接在决策树模型训练完成后,用pyplot绘制树状图展示决策路径,形成“数据处理→模型训练→结果可视化”的闭环,提升分析效率。
基于pyplot的树状图实现,按“数据复杂度”分为“基础层级树”“进阶样式树”“决策树可视化”三类场景,以下附完整代码与步骤解析。
核心需求:展示“公司→部门→小组”的三级架构,清晰区分层级,标注各小组人数。
用字典定义层级关系,键为“父节点”,值为“子节点列表+对应数值”:
import matplotlib.pyplot as plt
import numpy as np
# 1. 定义组织架构数据(三级层级:公司→部门→小组)
org_data = {
"某科技公司": [ # 一级节点
("技术部", [("算法组", 15), ("开发组", 20), ("测试组", 10)]), # 二级节点+三级节点
("业务部", [("电商组", 25), ("金融组", 18)]),
("职能部", [("人力组", 8), ("财务组", 6)])
]
}
通过递归遍历层级数据,计算每个节点的x(层级深度)、y(垂直位置)坐标,确保节点不重叠:
def calculate_coords(data, x_base=0, y_base=0, level=1, coords=None):
"""
递归计算节点坐标
x_base: 一级节点x坐标
y_base: 初始y坐标
level: 层级(1=一级,2=二级,3=三级)
coords: 存储坐标的字典
"""
if coords is None:
coords = {"nodes": [], "connections": []} # nodes: (x, y, label, value); connections: (x1,y1,x2,y2)
x = x_base + (level - 1) * 1.5 # 层级越深,x越大(横向树状图)
child_count = sum([len(children) if isinstance(children[0], tuple) else 1 for _, children in data.items()])
y_step = 8 / child_count # 垂直方向步长,避免节点重叠
current_y = y_base - 4 # 初始y位置(居中)
for parent, children in data.items():
# 处理父节点(一级/二级)
if level == 1:
parent_value = sum([v for _, sub_children in children for _, v in sub_children])
else:
parent_value = sum([v for _, v in children])
coords["nodes"].append((x, current_y, parent, parent_value))
# 处理子节点
for child in children:
if level == 2: # 二级节点的子节点是三级节点
child_label, child_value = child
child_x = x + 1.5
child_y = current_y
coords["nodes"].append((child_x, child_y, child_label, child_value))
# 记录父-子连接关系
coords["connections"].append((x, current_y, child_x, child_y))
current_y += y_step
else: # 一级节点的子节点是二级节点,递归处理
child_label, child_grand = child
child_x = x + 1.5
child_y = current_y
coords["nodes"].append((child_x, child_y, child_label, sum([v for _, v in child_grand])))
coords["connections"].append((x, current_y, child_x, child_y))
# 递归计算三级节点坐标
calculate_coords({child_label: child_grand}, x_base, current_y, level+1, coords)
current_y += y_step * len(child_grand)
return coords
# 计算坐标
coords = calculate_coords(org_data)
用barh绘制节点(水平条形图),用plot绘制连接线条,添加标签与数值:
# 设置画布大小
plt.figure(figsize=(12, 8))
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文显示问题
# 1. 绘制连接线条(先画线条,避免覆盖节点)
for (x1, y1, x2, y2) in coords["connections"]:
plt.plot([x1+0.4, x2-0.4], [y1, y2], color='#999999', linewidth=1) # 线条连接节点边缘
# 2. 绘制节点(按层级区分颜色)
colors = {1: '#4A90E2', 2: '#50E3C2', 3: '#F5A623'} # 一级=蓝,二级=绿,三级=橙
for (x, y, label, value) in coords["nodes"]:
level = int((x - 0) / 1.5) + 1 # 根据x坐标判断层级
# 绘制水平条形节点
bar = plt.barh(y, width=0.8, left=x, height=0.6, color=colors[level], alpha=0.8)
# 添加标签(节点名称+人数)
plt.text(x + 0.4, y, f"{label}n({value}人)", ha='center', va='center', fontsize=10, fontweight='bold')
# 3. 调整图形样式
plt.xlim(0, 6) # x轴范围
plt.ylim(-5, 5) # y轴范围
plt.axis('off') # 隐藏坐标轴
plt.title("某科技公司组织架构树状图", fontsize=16, fontweight='bold', pad=20)
# 保存图片
plt.tight_layout()
plt.savefig("org_tree.png", dpi=300, bbox_inches='tight')
plt.show()
生成的横向树状图中,一级节点(公司)、二级节点(部门)、三级节点(小组)通过颜色和位置区分,线条清晰连接父子关系,标签标注了小组人数,完全满足组织架构展示需求。
核心需求:将sklearn训练的决策树模型(预测用户购买意愿)用pyplot树状图展示,标注分支条件与预测结果。
from sklearn.tree import DecisionTreeClassifier, export_text
import matplotlib.pyplot as plt
import pandas as pd
# 1. 准备数据并训练决策树
data = pd.DataFrame({
"浏览时长(分)": [10, 5, 20, 3, 25, 8, 15, 2],
"是否加购": [1, 0, 1, 0, 1, 1, 0, 0],
"是否购买": [1, 0, 1, 0, 1, 0, 1, 0]
})
X = data[["浏览时长(分)", "是否加购"]]
y = data["是否购买"]
dt = DecisionTreeClassifier(max_depth=2) # 限制树深度为2,便于可视化
dt.fit(X, y)
# 2. 提取决策树结构(节点信息)
tree_structure = export_text(dt, feature_names=list(X.columns))
print("决策树结构:n", tree_structure)
# 3. 定义决策树节点坐标与绘制函数
def plot_decision_tree(dt, feature_names, class_names):
plt.figure(figsize=(10, 6))
plt.rcParams['font.sans-serif'] = ['SimHei']
# 递归绘制树节点
def recurse(node, x, y, width):
# 节点信息
if dt.tree_.children_left[node] == dt.tree_.children_right[node]: # 叶子节点
class_idx = dt.tree_.value[node].argmax()
plt.rectangle((x-width/2, y-0.2), x+width/2, y+0.2,
facecolor='#F5A623', edgecolor='black')
plt.text(x, y, f"预测:{'购买' if class_names[class_idx] == 1 else '不购买'}n样本数:{dt.tree_.n_node_samples[node]}",
ha='center', va='center', fontsize=9)
return
# 内部节点(分支条件)
feature_idx = dt.tree_.feature[node]
threshold = dt.tree_.threshold[node]
plt.rectangle((x-width/2, y-0.2), x+width/2, y+0.2,
facecolor='#4A90E2', edgecolor='black')
plt.text(x, y, f"{feature_names[feature_idx]}≤{threshold:.1f}?n样本数:{dt.tree_.n_node_samples[node]}",
ha='center', va='center', fontsize=9, fontweight='bold')
# 绘制左分支(满足条件)
left_node = dt.tree_.children_left[node]
plt.plot([x, x-width/2], [y-0.2, y-0.8], color='black', linewidth=1)
plt.text(x-width/4, y-0.5, "是", ha='center', va='center')
recurse(left_node, x-width/2, y-1, width/2)
# 绘制右分支(不满足条件)
right_node = dt.tree_.children_right[node]
plt.plot([x, x+width/2], [y-0.2, y-0.8], color='black', linewidth=1)
plt.text(x+width/4, y-0.5, "否", ha='center', va='center')
recurse(right_node, x+width/2, y-1, width/2)
# 开始绘制(根节点在顶部)
recurse(0, 0.5, 0.9, 0.8)
plt.xlim(0, 1)
plt.ylim(-1.5, 1.2)
plt.axis('off')
plt.title("用户购买意愿预测决策树", fontsize=14, fontweight='bold')
plt.savefig("decision_tree.png", dpi=300, bbox_inches='tight')
plt.show()
# 4. 绘制决策树
plot_decision_tree(dt, feature_names=list(X.columns), class_names=[0, 1])
树状图清晰展示了决策树的分支逻辑——以“浏览时长≤12.5分?”“是否加购≤0.5?”为条件,最终输出“购买”或“不购买”的预测结果,节点标注了样本数量,帮助业务人员快速理解用户购买的判断依据。
Pyplot树状图的核心优势是“适配层级数据的多样化场景”,在电商、金融、企业管理等领域均有广泛应用,典型场景如下:
将“大类→中类→小类”的商品结构与销量结合,用树状图展示:一级节点为“家电”“服饰”等大类,二级为“智能手机”“连衣裙”等中类,三级为具体商品;节点颜色深度对应销量高低,帮助运营快速识别高销量商品所在层级,优化库存分配。
基于客户“资产规模→信用评分→历史违约记录”构建层级树,节点标注风险等级(低/中/高),用红色标注高风险客户所在分支,为风控人员提供直观的客户风险画像,辅助贷款审批决策。
除决策树外,pyplot树状图还可用于展示聚类结果的层级关系(如层次聚类的树状图)、关联规则的推导路径,帮助数据分析师向非技术人员解释模型逻辑,降低沟通成本。
将“项目→阶段→任务→子任务”用树状图展示,节点标注完成率(如“80%”),用绿色表示已完成、黄色表示进行中、红色表示延期,让项目负责人清晰掌握任务推进情况。
原因:坐标计算未考虑节点数量,垂直/水平步长设置不合理;
解决方案:根据子节点数量动态调整步长(如“总高度/子节点数”),层级越深步长越小;用递归函数统一管理坐标计算,避免手动赋值误差。
原因:pyplot默认字体不支持中文;
解决方案:添加字体配置代码:plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'],同时设置英文备用字体。
原因:层级过深导致横向/纵向空间不足,节点挤压;
解决方案:① 采用“折叠树”逻辑,默认展示前3级,点击展开深层节点(需结合交互库如mpl_toolkits);② 调整画布大小(如figsize=(15, 10)),缩小节点高度/宽度,增加层级间距。
原因:坐标计算与数据强耦合,未封装通用函数;
解决方案:将坐标计算、绘图逻辑封装为通用函数(如plot_tree(data, direction='horizontal')),数据更新时仅需传入新的层级数据,无需修改绘图代码。
Pyplot树状图并非“开箱即用”的工具,但其“基础函数组合+高度定制化”的特性,使其成为Python生态中处理层级数据可视化的核心选择。其核心优势可概括为:
灵活可控:从节点样式到分支线条,全流程可定制,适配各类业务规范;
生态融合:与Pandas、sklearn等工具无缝衔接,嵌入数据分析流程更高效;
成本极低:无需额外安装依赖,Python数据分析环境默认支持。
未来拓展方向:结合交互库(如mpl_toolkits.mplot3d实现3D树状图、ipywidgets实现节点点击展开),提升树状图的交互性;结合颜色映射(cmap)实现节点与业务指标的深度关联,让可视化不仅“好看”更“有用”。
对于数据可视化从业者而言,掌握pyplot树状图的核心是“理解层级数据的坐标映射逻辑”——只要能将数据层级转化为合理的坐标系统,就能通过基础函数组合出满足业务需求的树状图,成为数据分析结果呈现的有力工具。

数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
做数据聚合时,PySpark的groupBy()确实能完成统计,这也是它的本职工作。但它有一个根本性局限:每一组数据,最终只能返回一行 ...
2026-10-01热力地图是数据可视化中极具辨识度与实用性的空间分析图表,结合地理空间维度与数据密度特征,通过颜色深浅、色阶渐变直观展示数 ...
2026-09-30 很多数据分析师做过按月份的销售额趋势图,画过按天的流量折线图,但当被问到“时间序列和普通数据有什么本质区别”“季节性 ...
2026-09-30同样是“银行数据岗”,在国有大行总行数据中心、在一家城商行的零售部、在银行系金融科技子公司、在保险公司,工作内容、成长节 ...
2026-09-29在数据分析与统计学研究中,数据往往不是独立存在的,不同变量之间普遍存在相互关联、相互影响的关系。相关性统计分析是挖掘变量 ...
2026-09-29 导读:大多数人只把 dataclasses 当成偷懒工具,用来少写 __init__、__repr__ 这类魔法方法。但它的能力远不止于此。本文带 ...
2026-09-29 很多数据分析师能熟练地计算指标、搭建标签体系,但当被问到“画像到底在解决什么问题”“画像和标签是什么关系”“画像如何 ...
2026-09-29在MySQL数据库运维与业务开发中,行业普遍存在“数据达到千万级就必须分表”的说法。但在实际生产环境中,千万条数据并不是强制 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 5W1H 分析法 定义:经典系统性思维框架,通过六个核心维度对问题进行全方位拆解与剖析,确 ...
2026-09-28 很多分析师在设计标签时思路清晰,但真到落地环节却面临“数据在手,不知如何转化为可用标签”的困境:或因加工方式选择不当 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 用户标签体系 定义: 通过一系列高度精炼的特征标识,对用户属性、行为与偏好进行量化刻画 ...
2026-09-24Pandas是Python生态中用于表格数据处理的核心库,广泛应用于数据清洗、统计运算、报表输出、数据分析建模等场景。在处理极大数值 ...
2026-09-24随着数字经济快速发展,数据已成为核心生产要素,各行各业的业务沉淀、用户行为、设备运行、市场交易均产生海量数据。数据处理作 ...
2026-09-24 很多分析师每天和数据打交道,但当被问到“标签是什么”“标签和指标有什么区别”“标签体系如何设计”时,却常常答不上来。 ...
2026-09-24在时序数据分析中,大部分业务数据并非持续平稳变化,而是会在某些时间节点出现突然抬升、断崖下跌、趋势反转、波动异变等现象, ...
2026-09-23在统计学与数据分析中,研究多组数据差异最常用的方法为单因素方差分析与事后多重比较。很多数据分析初学者容易混淆两者功能,认 ...
2026-09-23 很多数据分析师每天都在写 SQL,但当被问到“DQL 的本质是什么”“SELECT 子句的书写顺序与执行顺序为何不同”“INNER JOIN ...
2026-09-23 很多数据分析师写过无数个SELECT查询,但当被问到“如何新建一张表来固化中间数据”“创建视图和创建物理表有什么区别”“视 ...
2026-09-22CDA数据分析师 出品 作者:李诗怡 1. 金字塔原理 定义: 一种“先总后分、先结论后原因”的思考和表达方式。顶层为核心观点,中 ...
2026-09-22数据收集是数据分析、数据挖掘与数字化运营的源头工作,数据收集的完整性、准确性、时效性直接决定后续数据分析结果的可信度与业 ...
2026-09-21