资讯详情

Plotly Treemap 图表完全指南:从 px.treemap 到 go.Treemap 的分层数据可视化

📅 2026/9/21 15:20:25 | 华诺云谱 👁 阅读
Plotly Treemap 图表完全指南:从 px.treemap 到 go.Treemap 的分层数据可视化
Plotly Treemap 图表完全指南从 px.treemap 到 go.Treemap 的分层数据可视化【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址: https://gitcode.com/gh_mirrors/pl/plotly.pyTreemap树状矩形图用嵌套矩形直观呈现分层数据是 Plotly 生态中与 Sunburst、Icicle 并列的三种层级图之一输入数据格式完全相同由labels/names与parents定义层级。本文基于 plotly.py 仓库官方文档 doc/python/treemaps.md 展开结合源码实现覆盖从 Plotly Express 一键绘制、矩形 DataFrame 的path映射、连续/离散着色、缺失值处理到go.Treemap的高级属性branchvalues、maxdepth、pathbar、marker.colors/colorway/colorscale、圆角、统一字号与图案填充的完整实战方案。读完本文你将能针对任意分层数据集快速构建可交互、可下钻、可定制的 Treemap 图表。Treemap 图表基础与交互行为Treemap 使用嵌套矩形可视化分层数据层级由两个核心属性定义labelspx.treemap中为names每个节点的名称parents每个节点父节点的名称根节点的parents为空字符串。点击任意扇区可以放大/缩小查看图表左上角会同步显示一个pathbar路径条展示当前可见部分的完整层级路径同样可以通过 pathbar 逐级向上缩放回到更高层级。这一交互机制是 Treemap 区别于普通热力图/矩形图的关键体验。在仓库中go.Treemap轨迹类位于 plotly/graph_objs/_treemap.py自动生成文件其合法属性集合包括branchvalues、count、domain、hoverlabel、hovertemplate、ids、labels、level、marker、maxdepth、parents、pathbar、root、textfont、tiling、values等本文后续各节将逐一展开这些核心属性。使用 plotly.express 绘制基础 TreemapPlotly Express 是 Plotly 的高层接口详见 plotly-express 指南可处理多种类型的数据参见 px-arguments并易于定制样式参见 styling-plotly-express。使用px.treemap时DataFrame 的每一行对应 Treemap 中的一个扇区。最简单的用法是直接传入names与parents两个列表import plotly.express as px fig px.treemap( names [Eve,Cain, Seth, Enos, Noam, Abel, Awan, Enoch, Azura], parents [, Eve, Eve, Seth, Seth, Eve, Eve, Awan, Eve] ) fig.update_traces(root_colorlightgrey) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()这里root_colorlightgrey用于设置根节点Eve 的父节点即空字符串对应的隐形根的背景色margin参数控制图表四周留白以避免标签被裁剪。源码视角px.treemap 的参数与内部行为px.treemap的函数签名定义在 plotly/express/_chart_types.pydef treemap( data_frameNone, namesNone, valuesNone, parentsNone, idsNone, pathNone, colorNone, color_continuous_scaleNone, range_colorNone, color_continuous_midpointNone, color_discrete_sequenceNone, color_discrete_mapNone, hover_nameNone, hover_dataNone, custom_dataNone, labelsNone, titleNone, subtitleNone, templateNone, widthNone, heightNone, branchvaluesNone, maxdepthNone, ) - go.Figure:从源码可以看到三个重要的内部规则path与ids/parents互斥当同时传入path和ids或parents时会抛出ValueErrorEitherpathshould be provided, oridsandparents. These parameters are mutually exclusive...见 plotly/express/_chart_types.pypath模式下默认branchvaluestotal当传入path且未显式指定branchvalues时源码会自动将其设为totalplotly/express/_chart_types.pycolor_discrete_sequence映射到layout.treemapcolorway传入离散色序列时源码将其写入 layout 的treemapcolorway属性plotly/express/_chart_types.py最终通过make_figure(args, constructorgo.Treemap, trace_patchdict(branchvaluesbranchvalues, maxdepthmaxdepth), layout_patchlayout_patch)构建图表。矩形 DataFrame 的 Treemappath 参数分层数据往往以“矩形”DataFrame 存储不同的列对应层级的不同层次。px.treemap通过path参数接受一个列名列表来定义层级注意给定path时不应再提供ids和parents源码中已做互斥校验。import plotly.express as px df px.data.tips() fig px.treemap(df, path[px.Constant(all), day, time, sex], valuestotal_bill) fig.update_traces(root_colorlightgrey) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()此处px.Constant(all)创建一个值恒为all的虚拟列作为单一根节点从而保证所有数据挂在一个根下valuestotal_bill指定扇区面积所对应的数值列。这种虚拟根列技巧在本仓库官方文档的多处示例doc/python/treemaps.md中被反复使用。连续颜色映射color 数值列与加权平均着色当color参数对应数值型数据时节点的颜色由其子节点颜色按values加权平均计算得出。最佳实践确保path的第一个元素是单一根节点。下面的例子中我们创建一个每行取值相同的虚拟列来达成这一点。import plotly.express as px import numpy as np df px.data.gapminder().query(year 2007) fig px.treemap(df, path[px.Constant(world), continent, country], valuespop, colorlifeExp, hover_data[iso_alpha], color_continuous_scaleRdBu, color_continuous_midpointnp.average(df[lifeExp], weightsdf[pop])) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()关键参数说明colorlifeExp以数值列lifeExp驱动颜色color_continuous_scaleRdBu选用红-蓝发散色标color_continuous_midpoint用人口加权平均预期寿命作为色标中点使高于/低于平均水平的大洲与国家在颜色上直观分离hover_data[iso_alpha]在悬停提示中额外附加国家 ISO 代码列。仓库测试 tests/test_optional/test_px/test_px_functions.py 验证了该行为传入数值型color且不指定color_discrete_sequence时fig.layout.coloraxis.colorscale默认回退到Viridis连续色标而显式传入range_color(5, 15)时fig.layout.coloraxis.cmin/cmax会被正确设置。离散颜色映射color 类别列与混合色规则当color参数对应非数值类别数据时使用离散颜色。规则为如果一个扇区的所有子节点在color列上取值相同则使用该取值对应的颜色否则子节点颜色不一致使用离散色序中的第一个颜色表示混合。import plotly.express as px df px.data.tips() fig px.treemap(df, path[px.Constant(all), sex, day, time], valuestotal_bill, colorday) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()下面的例子则展示混合色的具体成因Saturday 和 Sunday 扇区只有 Dinner 记录因此颜色与 Dinner 一致而 Female - Friday 下同时存在 Lunch 与 Dinner 记录该扇区使用离散色序第一个颜色示例中为蓝色表示混合import plotly.express as px df px.data.tips() fig px.treemap(df, path[px.Constant(all), sex, day, time], valuestotal_bill, colortime) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()离散颜色的显式映射color_discrete_map通过color_discrete_map可以为类别值显式指定颜色。关于离散颜色的完整机制可参考仓库的 discrete-color 专题文档。import plotly.express as px df px.data.tips() fig px.treemap(df, path[px.Constant(all), sex, day, time], valuestotal_bill, colortime, color_discrete_map{(?):lightgrey, Lunch:gold, Dinner:darkblue}) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()其中(?)键用于指定未知/其他类别的兜底颜色这在存在缺失类别或混合扇区时非常有用。矩形数据中的缺失值处理当数据集并非完全矩形时缺失值必须以None显式填充否则层级关系无法正确构建。import plotly.express as px import pandas as pd vendors [A, B, C, D, None, E, F, G, H, None] sectors [Tech, Tech, Finance, Finance, Other, Tech, Tech, Finance, Finance, Other] regions [North, North, North, North, North, South, South, South, South, South] sales [1, 3, 2, 4, 1, 2, 2, 1, 4, 1] df pd.DataFrame( dict(vendorsvendors, sectorssectors, regionsregions, salessales) ) df[all] all # in order to have a single root node print(df) fig px.treemap(df, path[all, regions, sectors, vendors], valuessales) fig.update_traces(root_colorlightgrey) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()注意第 5、10 行的None表示这两个 vendor 属于 Other 类别下该层级不存在具体供应商其余行 vendor 完整同时通过df[all] all构造单一根节点。仓库测试 tests/test_optional/test_px/test_px_functions.py 中的test_sunburst_treemap_with_path_non_rectangular正是对这类非矩形数据场景的回归验证。Treemap 圆角扇区New in 5.12自 Plotly 5.12 起可通过marker.cornerradius为扇区配置圆角import plotly.express as px fig px.treemap( names [Eve,Cain, Seth, Enos, Noam, Abel, Awan, Enoch, Azura], parents [, Eve, Eve, Seth, Seth, Eve, Eve, Awan, Eve] ) fig.update_traces(markerdict(cornerradius5)) fig.show()cornerradius取值为圆角半径像素级数值越大圆角越明显常用于美化仪表盘与汇报图表。使用 go.Treemap 构建基础图表当 Plotly Express 无法满足定制需求时可使用plotly.graph_objects中更底层的go.Treemap类相关背景见 graph-objects 指南。与px.treemap一致此处同样使用labels与parents定义层级但参数名以轨迹属性的形式直接传入构造器import plotly.graph_objects as go fig go.Figure(go.Treemap( labels [Eve,Cain, Seth, Enos, Noam, Abel, Awan, Enoch, Azura], parents [, Eve, Eve, Seth, Seth, Eve, Eve, Awan, Eve], root_colorlightgrey )) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()从 plotly/graph_objs/_treemap.py 可以看出go.Treemap继承自BaseTraceType所有属性labels、parents、values、marker、pathbar等均通过属性设置器写入底层 dict这也是 Plotly 图对象可序列化、可比较、可更新的基础。go.Treemap 核心属性详解以下示例综合运用 Treemap 的核心属性官方文档 doc/python/treemaps.md 中列举如下values设置每个扇区关联的数值决定扇区面积占比textinfo控制图中显示的文本信息可选值包括text、value、current path、percent root、percent entry、percent parent或用组合如labelvaluepercent parentpathbarTreemap 的特色组件显示当前可见部分的层级路径也可用于向上缩放branchvalues决定values如何求和total扇区的values表示其全部后代之和。示例中 Eve 65恰等于 14 12 10 2 6 6 1 4其全部子孙之和remainder根与分支扇区的values表示除叶子求和之外的多余部分。下面的双面板示例用make_subplots并排对比两种branchvalues模式import plotly.graph_objects as go from plotly.subplots import make_subplots labels [Eve, Cain, Seth, Enos, Noam, Abel, Awan, Enoch, Azura] parents [, Eve, Eve, Seth, Seth, Eve, Eve, Awan, Eve] fig make_subplots( cols 2, rows 1, column_widths [0.4, 0.4], subplot_titles (branchvalues: bremainderbr /nbsp;br /, branchvalues: btotalbr /nbsp;br /), specs [[{type: treemap, rowspan: 1}, {type: treemap}]] ) fig.add_trace(go.Treemap( labels labels, parents parents, values [10, 14, 12, 10, 2, 6, 6, 1, 4], textinfo labelvaluepercent parentpercent entrypercent root, root_colorlightgrey ),row 1, col 1) fig.add_trace(go.Treemap( branchvalues total, labels labels, parents parents, values [65, 14, 12, 10, 2, 6, 6, 1, 4], textinfo labelvaluepercent parentpercent entry, root_colorlightgrey ),row 1, col 2) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()make_subplots中specs[[{type: treemap}, {type: treemap}]]声明两个子图均为 treemap 类型才能正确容纳go.Treemap轨迹。左侧remainder模式下根节点与中间分支的值是各自叶子之外的余量右侧total模式下则直接给出总和。branchvalues的枚举合法性在自动生成的 plotly/graph_objs/_treemap.py 中有定义branchvalues属性及其 setter。设置 Treemap 扇区颜色三种方式go.Treemap提供三种扇区着色途径官方文档 doc/python/treemaps.md 归类marker.colors直接为每个扇区指定颜色列表treemapcolorwaylayout 属性为同一层级提供循环使用的色序marker.colorscale按数值映射连续色标。方式一marker.colors 显式着色import plotly.graph_objects as go values [0, 11, 12, 13, 14, 15, 20, 30] labels [container, A1, A2, A3, A4, A5, B1, B2] parents [, container, A1, A2, A3, A4, container, B1] fig go.Figure(go.Treemap( labels labels, values values, parents parents, marker_colors [pink, royalblue, lightgray, purple, cyan, lightgray, lightblue, lightgreen] )) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()marker_colors的长度需与labels一一对应未显式指定的扇区将使用默认色序。方式二layout.treemapcolorway 循环色序treemapcolorway是 layout 级别的属性定义各层级扇区循环使用的颜色序列适合批量着色import plotly.graph_objects as go values [0, 11, 12, 13, 14, 15, 20, 30] labels [container, A1, A2, A3, A4, A5, B1, B2] parents [, container, A1, A2, A3, A4, container, B1] fig go.Figure(go.Treemap( labels labels, values values, parents parents, root_colorlightblue )) fig.update_layout( treemapcolorway [pink, lightgray], margin dict(t50, l25, r25, b25) ) fig.show()这里treemapcolorway [pink, lightgray]让各扇区在两种颜色间循环。这与px.treemap中color_discrete_sequence的映射机制一致见 plotly/express/_chart_types.py测试 tests/test_optional/test_px/test_px_functions.py 也验证了传入color_discrete_sequence后fig.data[0].marker.colors中的颜色全部落在该序列内。方式三marker.colorscale 连续色标import plotly.graph_objects as go values [0, 11, 12, 13, 14, 15, 20, 30] labels [container, A1, A2, A3, A4, A5, B1, B2] parents [, container, A1, A2, A3, A4, container, B1] fig go.Figure(go.Treemap( labels labels, values values, parents parents, marker_colorscale Blues )) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()marker_colorscale Blues使用内置蓝色连续色标按数值渐变着色。实战连续色标 双面板下钻maxdepth下面的完整示例将销售额扇区面积与电话成交率扇区颜色按 region - county - salesperson 层级进行可视化例如可以发现 East 大区整体表现不佳但 Tyler 县仍高于平均水平——不过其表现被销售员 GT 的低成交率拉低。右侧子图设置了maxdepth2只渲染前两层点击扇区可继续下钻到更深层级import plotly.graph_objects as go from plotly.subplots import make_subplots import pandas as pd df pd.read_csv(https://raw.githubusercontent.com/plotly/datasets/master/sales_success.csv) print(df.head()) levels [salesperson, county, region] # levels used for the hierarchical chart color_columns [sales, calls] value_column calls def build_hierarchical_dataframe(df, levels, value_column, color_columnsNone): Build a hierarchy of levels for Sunburst or Treemap charts. Levels are given starting from the bottom to the top of the hierarchy, ie the last level corresponds to the root. df_list [] for i, level in enumerate(levels): df_tree pd.DataFrame(columns[id, parent, value, color]) dfg df.groupby(levels[i:]).sum() dfg dfg.reset_index() df_tree[id] dfg[level].copy() if i len(levels) - 1: df_tree[parent] dfg[levels[i1]].copy() else: df_tree[parent] total df_tree[value] dfg[value_column] df_tree[color] dfg[color_columns[0]] / dfg[color_columns[1]] df_list.append(df_tree) total pd.Series(dict(idtotal, parent, valuedf[value_column].sum(), colordf[color_columns[0]].sum() / df[color_columns[1]].sum()), name0) df_list.append(total) df_all_trees pd.concat(df_list, ignore_indexTrue) return df_all_trees df_all_trees build_hierarchical_dataframe(df, levels, value_column, color_columns) average_score df[sales].sum() / df[calls].sum() fig make_subplots(1, 2, specs[[{type: domain}, {type: domain}]],) fig.add_trace(go.Treemap( labelsdf_all_trees[id], parentsdf_all_trees[parent], valuesdf_all_trees[value], branchvaluestotal, markerdict( colorsdf_all_trees[color], colorscaleRdBu, cmidaverage_score), hovertemplateb%{label} /b br Sales: %{value}br Success rate: %{color:.2f}, name ), 1, 1) fig.add_trace(go.Treemap( labelsdf_all_trees[id], parentsdf_all_trees[parent], valuesdf_all_trees[value], branchvaluestotal, markerdict( colorsdf_all_trees[color], colorscaleRdBu, cmidaverage_score), hovertemplateb%{label} /b br Sales: %{value}br Success rate: %{color:.2f}, maxdepth2 ), 1, 2) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()要点解析build_hierarchical_dataframe从叶子到根逐级groupby().sum()汇总为每个层级构造id/parent/value/color四列最终拼接成完整的层级表marker.colors直接传入每行计算的sales/calls比率cmidaverage_score设定色标中点整体平均成交率colorscaleRdBu以红蓝发散色标凸显高于/低于平均hovertemplate使用%{label}、%{value}、%{color:.2f}自定义悬停提示格式maxdepth2限制初始渲染层级数未展示的层级可通过点击逐级下钻——这是大规模分层数据先看全局、再钻细节的推荐实践。嵌套层级与 maxdepth 控制当分层数据包含多层分组时Treemap 与 Sunburst参见 sunburst-charts 文档都能揭示数据内在结构。maxdepth属性控制从给定层级开始渲染的扇区数量import plotly.graph_objects as go import pandas as pd df pd.read_csv(https://raw.githubusercontent.com/plotly/datasets/96c0bd/sunburst-coffee-flavors-complete.csv) fig go.Figure() fig.add_trace(go.Treemap( ids df.ids, labels df.labels, parents df.parents, maxdepth3, root_colorlightgrey )) fig.update_layout(margin dict(t50, l25, r25, b25)) fig.show()这里同时给出ids每个节点的唯一标识即使标签重复也能准确定位与labels、parentsmaxdepth3表示最多渲染 3 层扇区更深层需交互下钻。使用 uniformtext 统一标签字号layout.uniformtext可强制所有文本标签使用相同字号避免长标签自动缩小导致的视觉不统一minsize统一的最小字号mode放不下时如何处理——hide隐藏该标签show则允许溢出显示。注意使用uniformtext时动画过渡animated transitions目前尚未实现。import plotly.graph_objects as go import pandas as pd df pd.read_csv(https://raw.githubusercontent.com/plotly/datasets/96c0bd/sunburst-coffee-flavors-complete.csv) fig go.Figure(go.Treemap( ids df.ids, labels df.labels, parents df.parents, pathbar_textfont_size15, root_colorlightgrey )) fig.update_layout( uniformtextdict(minsize10, modehide), margin dict(t50, l25, r25, b25) ) fig.show()pathbar_textfont_size15单独控制路径条文本字号uniformtextdict(minsize10, modehide)则让所有扇区标签字号至少为 10px放不下的标签直接隐藏从而保持版面干净。图案填充Pattern FillsNew in 5.15自 Plotly 5.15 起Treemap 在颜色之外还支持图案填充hatching/texture完整机制见 pattern-hatching-texture 专题文档。下面的例子为根节点应用竖直条纹图案import plotly.graph_objects as go fig go.Figure( go.Treemap( labels [Eve,Cain, Seth, Enos, Noam, Abel, Awan, Enoch, Azura], parents[, Eve, Eve, Seth, Seth, Eve, Eve, Awan, Eve], root_colorlightgrey, textfont_size20, markerdict(patterndict(shape[|], solidity0.80)), ) ) fig.show()marker.pattern支持shape图案形状如|、/、-等与solidity填充密度0~1等参数常用于黑白打印场景或为特殊扇区做视觉强调。总结与延伸阅读Treemap 是 Plotly 分层可视化体系中表达部分-整体关系最紧凑的方案px.treemap一行代码即可完成矩形 DataFrame 到嵌套矩形的映射go.Treemap则提供branchvalues、maxdepth、pathbar、marker着色与图案填充等细粒度控制。结合点击缩放、pathbar 逐级导航与自定义hovertemplateTreemap 足以承载从电商品类销售、地理销售漏斗到基因表达等多层数据的探索分析。相关仓库资源可继续深入doc/python/treemaps.md本文所依据的官方指南原文plotly/express/_chart_types.pypx.treemap源码实现plotly/graph_objs/_treemap.pygo.Treemap轨迹类的属性定义tests/test_optional/test_px/test_px_functions.pytreemap 连续/离散色标的测试用例doc/python/sunburst-charts.md 与 doc/python/icicle-charts.md使用相同输入数据格式的姊妹图表类型doc/python/discrete-color.md 与 doc/python/pattern-hatching-texture.md着色与图案填充的底层机制。【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址: https://gitcode.com/gh_mirrors/pl/plotly.py创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。