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
相关产品推荐
相关产品推荐

