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

Dash Python中图表未与Callback交互问题排查

问题诊断与解决方案

核心问题分析

你的Dash图表无数据显示,但调用show()能在新标签页打开,主要有以下几个关键问题:

  1. 布局中缺少目标Graph组件:回调指定输出到id='fatPrevLinhas'的figure属性,但代码里未展示布局中是否添加了dcc.Graph(id='fatPrevLinhas'),这是图表无法渲染的最直接原因。
  2. 多选项Dropdown初始值格式错误:当Dropdown设置multi=True时,value必须是列表类型(比如["Todos"]),而你用了字符串"Todos",会导致初始回调逻辑异常。
  3. 数据生成依赖未定义:代码中random.choices(departamentos, ...)里的departamentos、categorias、produtos三个列表未定义,运行时会抛出NameError,导致DataFrame生成失败。

分步修复方案

1. 补充布局中的Graph组件

在Dash应用布局里,必须添加对应id的dcc.Graph组件,示例如下:

app.layout = dbc.Container([
    dbc.Row([filter1]),  # 放入你的筛选器
    dbc.Row([
        dbc.Col([
            dcc.Graph(id='fatPrevLinhas')  # 必须添加这个组件,回调才能输出图表
        ])
    ])
])

2. 修正Dropdown的初始值

将Dropdown的value改为列表格式:

dcc.Dropdown(
    id="filtroDepartamento",
    className="filtro",
    options=[{'label':'Todos', 'value': 'Todos'},
            {'label':'Acessórios', 'value': 'Acessórios'},
            {'label':'Colchões', 'value': 'Colchões'},
            {'label':'Enxoval', 'value': 'Enxoval'},
            {'label':'Móveis', 'value': 'Móveis'},
            {'label':'Puericultura Leve', 'value': 'Puericultura Leve'},
            {'label':'Puericultura Pesada', 'value': 'Puericultura Pesada'}],
    value=["Todos"],  # 改为列表,适配multi=True
    multi=True
)

3. 定义数据生成依赖的列表

在DataFrame生成前,添加departamentos、categorias、produtos的定义:

# 定义缺失的列表变量
departamentos = ['Acessórios', 'Colchões', 'Enxoval', 'Móveis', 'Puericultura Leve', 'Puericultura Pesada']
categorias = ['Categoria1', 'Categoria2', 'Categoria3']  # 可根据需求修改
produtos = ['ProdutoA', 'ProdutoB', 'ProdutoC']  # 可根据需求修改

完整修正后的代码

import datetime
import pandas as pd
import random
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from dash.dependencies import Input, Output

# 初始化Dash应用
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

# 定义缺失的列表变量
departamentos = ['Acessórios', 'Colchões', 'Enxoval', 'Móveis', 'Puericultura Leve', 'Puericultura Pesada']
categorias = ['Categoria1', 'Categoria2', 'Categoria3']
produtos = ['ProdutoA', 'ProdutoB', 'ProdutoC']

# Create a dataframe 
start_date_str = '2023-04-01'
end_date_str = datetime.date.today().strftime('%Y-%m-%d')
datas = pd.date_range(start=start_date_str, end=end_date_str, freq='D').to_list()
fatData = pd.DataFrame(index=datas)
fatData['Departamento'] = random.choices(departamentos, k=len(fatData))
fatData['Categoria'] = random.choices(categorias, k=len(fatData))
fatData['Produto'] = random.choices(produtos, k=len(fatData))
fatData['Faturamento'] = np.random.randint(500000, 900000, size=len(datas))
fatData['Previsão'] = np.random.randint(600000, 800000, size=len(datas))
fatData = fatData.reset_index()
fatData = fatData.rename(columns={'index': 'Data'})

#Create a filter
filter1 = dbc.Col([
    html.Label('Departamento', className='title_filter'),
    dcc.Dropdown(
        id="filtroDepartamento",
        className="filtro",
        options=[{'label':'Todos', 'value': 'Todos'},
                {'label':'Acessórios', 'value': 'Acessórios'},
                {'label':'Colchões', 'value': 'Colchões'},
                {'label':'Enxoval', 'value': 'Enxoval'},
                {'label':'Móveis', 'value': 'Móveis'},
                {'label':'Puericultura Leve', 'value': 'Puericultura Leve'},
                {'label':'Puericultura Pesada', 'value': 'Puericultura Pesada'}],
        value=["Todos"],  # 修正为列表格式
        multi=True
    )
], className='filter text-center')

# 定义应用布局
app.layout = dbc.Container([
    dbc.Row([filter1], className="my-3"),
    dbc.Row([
        dbc.Col([
            dcc.Graph(id='fatPrevLinhas')  # 添加目标Graph组件
        ])
    ])
], fluid=True)

#Callback
@app.callback(
    Output('fatPrevLinhas', 'figure'),
    Input('filtroDepartamento', 'value')
)
def update_my_graph(departamento):
    if len(departamento) > 0:
        if 'Todos' in departamento:
            dff = fatData
        else:
            dff = fatData[fatData["Departamento"].isin(departamento)]
        fatPrevLinhas = go.Figure()
        fatPrevLinhas.add_trace(go.Scatter(x=dff['Data'], y=dff['Previsão'], mode='lines', name='Previsão', line=dict(color='gray', width=2, dash='dash')))
        fatPrevLinhas.add_trace(go.Scatter(x=dff['Data'], y=dff['Faturamento'], mode='lines', name='Faturamento', line=dict(color='blue', width=2)))
        fatPrevLinhas.update_layout(
            title_text='Faturamento vs Previsão',
            xaxis_title='Data',
            yaxis_title='Faturamento (R$)'
        )
        return fatPrevLinhas
    elif len(departamento) == 0:
        raise dash.exceptions.PreventUpdate

# 运行应用
if __name__ == '__main__':
    app.run_server(debug=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:53:19