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

在Dash仪表盘中如何为Plotly多轨迹设置不同子类别颜色?

解决Dash仪表盘中子类别轨迹颜色一致的问题

我使用包含Date、Category、Sub-category、Expenditure四列的数据集,想要创建Dash仪表盘展示所选类别及其子类别随日期变化的支出情况。当前通过以下代码生成图表,但所有轨迹颜色一致,请问如何为不同子类别对应的轨迹设置不同颜色?

cats = df.Category.unique()
tags={key: [] for key in cats}
for cat in cats:
    tags[cat] = df[df.Category==cat].Subcat.unique()

@callback(Output(graph,"figure"),Input(dropdown,"value"))
def update_bar_chart(cat):
    mask = df['Category']==cat
    fig = px.bar(df[mask].groupby(df.Date)['Expense amount'].sum())
    for i, tag in enumerate(tags[cat]):
        mask = df['Subcat']==tag
        fig.add_traces(list(px.scatter(df[mask].groupby(df.Date)['Expense amount'].sum()).select_traces()))
    return fig

问题原因

每次独立调用px.scatter()时,Plotly会默认使用颜色序列的第一个颜色,导致所有子类别轨迹颜色重复。

解决方案1:手动指定每个子类别颜色

通过预定义颜色序列,在循环添加轨迹时为每个子类别分配不同颜色:

import plotly.colors as pc

cats = df.Category.unique()
tags={key: [] for key in cats}
for cat in cats:
    tags[cat] = df[df.Category==cat].Subcat.unique()

# 选用Plotly内置定性颜色序列,也可自定义颜色列表
color_sequence = pc.qualitative.Plotly

@callback(Output(graph,"figure"),Input(dropdown,"value"))
def update_bar_chart(cat):
    mask = df['Category']==cat
    # 重置索引让Plotly正确识别轴字段
    total_df = df[mask].groupby(df.Date)['Expense amount'].sum().reset_index(name='Total')
    fig = px.bar(total_df, x='Date', y='Total')
    
    for i, tag in enumerate(tags[cat]):
        mask_sub = df['Subcat']==tag
        sub_df = df[mask_sub].groupby(df.Date)['Expense amount'].sum().reset_index(name='Expense amount')
        scatter_fig = px.scatter(sub_df, x='Date', y='Expense amount')
        
        # 给当前子类别轨迹分配颜色
        trace = scatter_fig.select_traces()[0]
        trace.marker.color = color_sequence[i % len(color_sequence)]
        # 设置轨迹名称为子类别名,方便图例识别
        trace.name = tag
        fig.add_trace(trace)
    
    fig.update_layout(legend_title_text="子类别")
    return fig

解决方案2:按子类别分组自动分配颜色(更简洁)

重构代码,先按Date和Subcat分组聚合数据,直接用px.scatter()按子类别分组,Plotly会自动为每个子类别分配不同颜色:

cats = df.Category.unique()
tags={key: [] for key in cats}
for cat in cats:
    tags[cat] = df[df.Category==cat].Subcat.unique()

@callback(Output(graph,"figure"),Input(dropdown,"value"))
def update_bar_chart(cat):
    mask = df['Category']==cat
    # 生成总支出柱状图
    total_df = df[mask].groupby('Date')['Expense amount'].sum().reset_index(name='Total')
    fig = px.bar(total_df, x='Date', y='Total', title=f"{cat} 类别总支出")
    
    # 按日期+子类别聚合支出数据
    subcat_df = df[mask].groupby(['Date', 'Subcat'])['Expense amount'].sum().reset_index()
    # 通过color参数指定按子类别区分颜色
    scatter_fig = px.scatter(subcat_df, x='Date', y='Expense amount', color='Subcat')
    
    # 将散点轨迹添加到柱状图中
    fig.add_traces(scatter_fig.select_traces())
    
    # 优化布局细节
    fig.update_layout(
        legend_title_text="子类别",
        xaxis_title="日期",
        yaxis_title="支出金额"
    )
    return fig

关键说明

  • 两种方法都需要用reset_index()将聚合后的Series转换为DataFrame,确保Plotly能正确识别轴字段。
  • 第二种方法更易维护,Plotly会自动处理颜色映射、图例标签等细节,减少冗余代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:17:49