如何解决Plotly旭日图内层颜色与数值总和不匹配问题?
Plotly旭日图内层颜色不匹配总和值的问题与修复
问题描述
我制作了一个Plotly旭日图,外层颜色显示正确(对应数值为32k)。鼠标悬停时,内层显示所有外层数值的总和(约64k),但颜色却对应16k的数值。修改示例后,最内层“a”的数值总和为10,应显示橙色,但实际颜色不符。
可复现代码
from pandas import DataFrame import plotly.express as px A = ["a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c"] B = ["b11", "b12", "b21", "b22", "b31", "b32", "b11", "b12", "b21", "b22", "b31", "b32"] C = ["c111", "c112", "c121", "c122", "c211", "c212", "c221", "c222", "c311", "c312", "c321", "c322"] C_values = [1, 2, 3, 4, 2, 3, 1, 2, 3, 4, 2, 3] df = DataFrame(dict(A=A, B=B, C=C, C_values=C_values)) fig = px.sunburst(df, path=["A", "B", "C"], values="C_values", color="C_values", color_continuous_scale=[(0, "green"), (0.5, "yellow"), (1, "red")], range_color=(0, 15)) fig.show()
问题原因
- 默认情况下,
px.sunburst的color参数直接调用原始数据列的数值,不会自动计算父节点的数值总和 - 内层节点的颜色实际是基于子节点
C_values的平均值(默认聚合方式),而非总和,导致颜色与悬停显示的总和数值不匹配
修复方案
需要手动计算各层级节点的数值总和,将总和作为颜色映射的依据:
修改后的代码
from pandas import DataFrame import plotly.express as px A = ["a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c"] B = ["b11", "b12", "b21", "b22", "b31", "b32", "b11", "b12", "b21", "b22", "b31", "b32"] C = ["c111", "c112", "c121", "c122", "c211", "c212", "c221", "c222", "c311", "c312", "c321", "c322"] C_values = [1, 2, 3, 4, 2, 3, 1, 2, 3, 4, 2, 3] df = DataFrame(dict(A=A, B=B, C=C, C_values=C_values)) # 计算各层级的总和 # 计算B层级的总和 b_totals = df.groupby(['A', 'B'])['C_values'].sum().reset_index(name='b_total') df = df.merge(b_totals, on=['A', 'B']) # 计算A层级的总和 a_totals = df.groupby(['A'])['C_values'].sum().reset_index(name='a_total') df = df.merge(a_totals, on=['A']) # 为每个层级节点分配对应总和值 df['color_value'] = df['C_values'] # 给B层级节点分配B组总和 df.loc[df.duplicated(subset=['A', 'B'], keep='first'), 'color_value'] = df['b_total'] # 给A层级节点分配A组总和 df.loc[df.duplicated(subset=['A'], keep='first'), 'color_value'] = df['a_total'] fig = px.sunburst(df, path=["A", "B", "C"], values="C_values", color="color_value", color_continuous_scale=[(0, "green"), (0.5, "yellow"), (1, "red")], range_color=(0, 15)) fig.show()
效果说明
修改后:
- 最外层C节点的颜色基于自身
C_values值,保持正确 - 中间层B节点的颜色基于对应B组的
C_values总和 - 最内层A节点的颜色基于对应A组的
C_values总和 - 示例中“a”节点的总和为10,会匹配
range_color=(0,15)的中间色调,符合预期
内容的提问来源于stack exchange,提问作者Sebastian Tramposch
相关产品推荐
相关产品推荐

