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

Dash Plotly报错LayoutIsNotDefined,求PyCharm环境下解决方案

解决Dash应用中LayoutIsNotDefined错误的方案

嘿,我看到你遇到了Dash运行时的LayoutIsNotDefined错误,别担心,这不是PyCharm和代码语法不兼容的问题,只是代码里一个小疏忽导致的。

错误原因

Dash在绑定回调函数之前,必须明确知道应用的布局结构。你代码里虽然定义了layout变量,但没有把它赋值给Dash应用实例的app.layout属性,所以Dash找不到应用的布局,就抛出了这个错误。

快速修复方案

只需要把你定义的布局变量赋值给app.layout就行,有两种方式:

  • 直接将布局赋值给app.layout:
    把原来的layout = html.Div([...])改成:

    app.layout = html.Div([
        # 你的布局内容保持不变
    ])
    
  • 先定义layout变量,再赋值给app.layout:
    在定义完layout变量后,添加一行:

    app.layout = layout
    

修正后的完整代码

import os
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

df = pd.read_csv('MNM_Rotterdam_5_Daily_Details-20191216081027.csv', error_bad_lines=False)
df['Date'] = pd.to_datetime(df.Date, infer_datetime_format=True)

if 'DYNO' in os.environ:
    app_name = os.environ['DASH_APP_NAME']
else:
    app_name = 'dash-timeseriesplot'

# 这里把layout赋值给app.layout
app.layout = html.Div([
    html.H1("GSM", style={'textAlign': 'center'}),
    dcc.Dropdown(id='my-dropdown',
                 options=[
                     {'label': 'Voice_SetupFailRate_2G', 'value': 'Voice_SetupFailRate_2G'},
                     {'label': 'Voice_DropRate_2G', 'value': 'Voice_DropRate_2G'},
                     {'label': 'OutgHandover_SuccesRate_2G', 'value': 'OutgHandover_SuccesRate_2G'},
                     {'label': 'Packet_SetupFailRate_2G', 'value': 'Packet_SetupFailRate_2G'},
                     {'label': 'Packet_DLMBytes_2G', 'value': 'Packet_DLMBytes_2G'},
                     {'label': 'Availability_2G', 'value': 'Availability_2G'}
                 ],
                 multi=True,
                 value=['Voice_SetupFailRate_2G'],
                 style={"display": "block","margin-left": "auto","margin-right": "auto","width": "60%"}),
    dcc.Graph(id='my-graph')
], className="container")

@app.callback(Output('my-graph', 'figure'),
              [Input('my-dropdown', 'value')])
def update_graph(selected_dropdown_value):
    dropdown = {"Voice_SetupFailRate_2G": "Voice_SetupFailRate_2G",
                "Voice_DropRate_2G": "Voice_DropRate_2G",
                "OutgHandover_SuccesRate_2G": "OutgHandover_SuccesRate_2G",
                "Packet_SetupFailRate_2G": "Packet_SetupFailRate_2G",
                "Packet_DLMBytes_2G": "Packet_DLMBytes_2G",
                "Availability_2G": "Availability_2G"}
    trace1 = []
    trace2 = []
    for GSM in selected_dropdown_value:
        trace1.append(go.Scatter(x=df[df["GSM"] == GSM]["Date"],
                                 y=df[df["GSM"] == GSM]["Open"],
                                 mode='lines', opacity=0.7,
                                 name=f'Open {dropdown[GSM]}',
                                 textposition='bottom center'))
        trace2.append(go.Scatter(x=df[df["GSM"] == GSM]["Date"],
                                 y=df[df["GSM"] == GSM]["Close"],
                                 mode='lines', opacity=0.6,
                                 name=f'Close {dropdown[GSM]}',
                                 textposition='bottom center'))
    traces = [trace1, trace2]
    data = [val for sublist in traces for val in sublist]
    figure = {'data': data,
              'layout': go.Layout(colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
                                 height=600,
                                 title=f"Opening and Closing Prices for {', '.join(str(dropdown[i]) for i in selected_dropdown_value)} Over Time",
                                 xaxis={"title":"Date",
                                        'rangeselector': {'buttons': list([
                                            {'count': 1, 'label': '1M', 'step': 'month', 'stepmode': 'backward'},
                                            {'count': 6, 'label': '6M', 'step': 'month', 'stepmode': 'backward'},
                                            {'step': 'all'}
                                        ])},
                                        'rangeslider': {'visible': True},
                                        'type': 'date'},
                                 yaxis={"title":"Price (USD)"})}
    return figure

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

补充说明

错误提示里提到的app.config['suppress_callback_exceptions']=True只是用来抑制警告的,不建议这么做,因为它没有解决布局未定义的根本问题,只是让Dash忽略这个检查,可能会导致后续其他隐藏问题。

内容的提问来源于stack exchange,提问作者Mahmoud Al-Haroon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:37:50