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

Dash回调中创建表格生成柱状图遇筛选无输出问题求助

问题排查与修复方案

1. 处理空筛选条件的情况

当用户未选择任何月份/国家时,month或country的值为None,此时df['Month'].isin(None)会返回全False,导致filtered_df为空,后续无数据可用于生成图表。需要添加空值判断,默认包含所有选项:

def coverage_rate(month, country):
    # 未选择时默认包含所有月份/国家
    if not month:
        month = df['Month'].unique()
    if not country:
        country = df['COUNTRY_NAME'].unique()
    
    month_mask = df['Month'].isin(month)
    country_mask = df['COUNTRY_NAME'].isin(country)
    
    filtered_df = df[country_mask & month_mask]
    
    # 筛选后无数据时返回提示图表
    if filtered_df.empty:
        return px.bar(title="无匹配数据,请调整筛选条件")

2. 避免除以0的错误

当filtered_df为空或零售总额为0时,total_retail会等于0,后续除法运算会触发错误,导致图表无法生成。需提前判断并处理:

grouped_df = filtered_df.groupby(['SKU']).agg({'quantity': 'sum','price': 'mean'}).reset_index()
grouped_df['retail'] = grouped_df['quantity'] * grouped_df['price']
total_retail = grouped_df['retail'].sum()

if total_retail == 0:
    return px.bar(title="零售总额为0,无法计算指数")

3. 替换低效的循环赋值

原代码用iterrows()循环修改index列,效率低且易引发警告,改用向量运算直接计算:

# 替换原循环部分
compet_grouped_df['index'] = (compet_grouped_df['retail'] / total_retail) * 100

4. 给下拉框设置默认值(可选)

在布局中给下拉框添加默认选中全部选项,避免初始状态无数据:

dcc.Dropdown(
    id='month_dd',
    options=list(df['Month'].unique()),
    multi=True,
    value=list(df['Month'].unique())  # 默认全选月份
),
dcc.Dropdown(
    id='country_dd',
    options=list(df['COUNTRY_NAME'].unique()),
    multi=True,
    value=list(df['COUNTRY_NAME'].unique())  # 默认全选国家
),

完整修复后的代码

import pandas as pd
import plotly.express as px
from dash import Dash, html, Input, Output, dcc

# 此处添加你的数据加载代码,例如:
# df = pd.read_excel("你的数据文件.xlsx")

app = Dash(__name__)

app.layout = html.Div([
    'Month', 
    dcc.Dropdown(
        id='month_dd',
        options=list(df['Month'].unique()), 
        multi=True,
        value=list(df['Month'].unique())
    ),  
    'Country', 
    dcc.Dropdown(
        id='country_dd', 
        options=list(df['COUNTRY_NAME'].unique()), 
        multi=True,
        value=list(df['COUNTRY_NAME'].unique())
    ),
    dcc.Graph(id='graph')
])

@app.callback(
    Output('graph', 'figure'),
    Input('month_dd', 'value'), 
    Input('country_dd', 'value'))

def coverage_rate(month, country):
    if not month:
        month = df['Month'].unique()
    if not country:
        country = df['COUNTRY_NAME'].unique()
    
    month_mask = df['Month'].isin(month)
    country_mask = df['COUNTRY_NAME'].isin(country)
    
    filtered_df = df[country_mask & month_mask]
    
    if filtered_df.empty:
        return px.bar(title="无匹配数据,请调整筛选条件")
    
    grouped_df = filtered_df.groupby(['SKU']).agg({'quantity': 'sum','price': 'mean'}).reset_index()
    grouped_df['retail'] = grouped_df['quantity'] * grouped_df['price']
    total_retail = grouped_df['retail'].sum()
    
    if total_retail == 0:
        return px.bar(title="零售总额为0,无法计算指数")
    
    compet_grouped_df = filtered_df.groupby(['SKU', 'Compet SKU', 'Brand']).agg({'quantity': 'sum','price': 'mean'}).reset_index()
    compet_grouped_df['retail'] = compet_grouped_df['quantity'] * compet_grouped_df['price']
    
    compet_grouped_df['index'] = (compet_grouped_df['retail'] / total_retail) * 100
    
    fig = px.bar(
        compet_grouped_df, 
        x='Brand', 
        y='index',
        title='品牌零售占比指数'
    )
    return fig 

if __name__ == '__main__': 
    app.run_server(debug=True)

关键修复点总结

  • 处理空筛选条件,避免无数据返回
  • 增加除以0的判断,防止计算错误
  • 用向量运算替代循环,提升效率并避免警告
  • 可选:设置下拉框默认全选,初始状态即可显示图表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:25:08