Plotly中graph_objects绘制Sunburst图缺失外层区块问题
Plotly Graph Objects Sunburst 标签缺失、节点错位问题解决
问题现象
使用plotly.graph_objects绘制Sunburst图时,对比同数据下plotly.express生成的图表,会出现以下异常:
- 部分标签缺失,外层区块完全不显示
- 数据实际存在,但展开节点时,部分子节点会从错误的父节点自动移动到正确位置(例如
btnCancel初始显示在dlgMessageBox下,展开后跳转到frmRibbonConfigureOffsets) - 更换其他数据格式时,甚至会直接导致图表为空
代码对比
问题代码(graph_objects)
import plotly.graph_objects as go # 存在层级问题的示例数据 faulty_data = { "ids": ["dlgMessageBox", "btnCancel", "frmRibbonConfigureOffsets", "btnOK"], "labels": ["Message Box", "Cancel", "Configure Offsets", "OK"], "parents": ["frmRibbonConfigureOffsets", "dlgMessageBox", "", "dlgMessageBox"], "values": [5, 3, 10, 2] } fig = go.Figure(go.Sunburst( ids=faulty_data["ids"], labels=faulty_data["labels"], parents=faulty_data["parents"], values=faulty_data["values"] )) fig.show()
正常代码(plotly.express)
import plotly.express as px import pandas as pd # 同一份数据转成DataFrame df = pd.DataFrame({ "parent": ["frmRibbonConfigureOffsets", "dlgMessageBox", "", "dlgMessageBox"], "label": ["Message Box", "Cancel", "Configure Offsets", "OK"], "value": [5, 3, 10, 2] }) fig = px.sunburst(df, path=['parent', 'label'], values='value') fig.show()
问题原因
plotly.graph_objects的Sunburst组件对数据层级的严谨性要求远高于plotly.express:
- 父节点存在性:所有
parents中的值必须在ids列表中存在,包括顶层节点(顶层节点的parent需设为空字符串""或None) - 节点顺序:父节点必须在其子节点之前出现在
ids列表中,否则初始渲染时无法识别层级关系 - 层级映射准确性:子节点的
parent必须严格对应正确的父节点id,拼写错误或层级混淆会导致节点归属错误
plotly.express会自动补全缺失的父节点、调整节点顺序,因此能规避这些问题;但graph_objects完全依赖用户提供的精准层级数据,初始渲染时无法自动修正,只能在展开节点时重新计算层级,导致节点“跳位”现象。
解决方案
- 校验层级映射:确保每个子节点的
parent值完全匹配父节点的id,顶层节点的parent设为空字符串 - 调整节点顺序:将父节点放在所有子节点之前加入
ids列表 - 参考express的输出结构:可以先用
plotly.express生成正确的Sunburst图,然后通过fig.data[0].ids、fig.data[0].parents提取标准格式的数据,再代入graph_objects中使用 - 修复后代码示例:
import plotly.graph_objects as go # 修正后的层级数据 fixed_data = { "ids": ["frmRibbonConfigureOffsets", "dlgMessageBox", "btnCancel", "btnOK"], "labels": ["Configure Offsets", "Message Box", "Cancel", "OK"], "parents": ["", "frmRibbonConfigureOffsets", "frmRibbonConfigureOffsets", "dlgMessageBox"], "values": [10, 5, 3, 2] } fig = go.Figure(go.Sunburst( ids=fixed_data["ids"], labels=fixed_data["labels"], parents=fixed_data["parents"], values=fixed_data["values"] )) fig.update_layout(margin=dict(t=0, l=0, r=0, b=0)) fig.show()
内容的提问来源于stack exchange,提问作者mattK.PH
相关产品推荐
相关产品推荐

