在故障排除 app.layout 和回调时遇到问题

Having issues troubleshooting app.layout and callbacks

我正在尝试显示带有趋势线的散点图,该散点图也有一个下拉菜单。我仍在学习 Dash-Plotly,并且在调试我做错的事情时遇到了麻烦。我使用了 dash tutorial 和许多其他 Whosebug 帖子,但我没有得到我需要做的事情。我以为我正确地完成了所有回调并正确设置了我的 app.layout。

我的代码:

app.layout = html.Div([
    html.H1('King County Housing Data: 1900-2015', style = {'text-align': 'center'}),

    dcc.Dropdown(id='grade-selector',  # geo-dropdown is what you'll see with the drop down
                 # Create a loop that pulls the unique values from the grade column and it values for the dropdown
                 options=[{'label': i, 'value': i}  # Creates the unique properties for the dropdown
                          for i in df['grade'].unique()],
                 value=7,
                 multi = False,
                 style={'width', '40%'}),  # value = default value for the dropdown)
    html.Div(id='output-container'),
    dcc.Graph(id='grade-price')
])



# Set up the callback functions: This is what connects all the figures and things together
@app.callback(
    # A call back needs two things, a input and an output
    [Output(component_id='output-container', component_property='children'),
     Output(component_id='grade-price', component_property='figure')],
    [Input(component_id='grade_selector', component_property='value')]
)

# Connecting Plotly graphs to Dash Components:

# **NOTE** Your arguments are tied to the number of inputs that you have. If you have only one input, then you'll
# Only have one argument.

def gupdate_output_div(grade_selector): # The argument refers to the Input's Component Property.
    print(grade_selector)
    print(type(grade_selector))
    container = 'The grade the user selected was {}'.format(grade_selector)

    # Creating a copy of the dataframe, not smart to mess around with the primary DataFrame in here
    dff = df.copyy()
    dff = dff[dff['grade']== grade_selector] # You are sorting the DF by what the user has selected

    # Plotly Express:
    fig = px.scatter(dff, x='sqft_living', y='price', color='view', marginal_y='violin',
                     marginal_x='box', trendline='ols', template='plotly_dark')

    return container, fig # What you return here is actually going to go into the output!
# If you have two Outputs, you're returning two things, three Outputs --> three returns


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

我的数据:

display(df[['price','sqft_living','grade']].head())
       price  sqft_living  grade
0  13.180632     7.501082      7
1  13.515081     8.384804      8
2  13.345507     7.306531      7
3  13.296317     7.319865      7
4  13.091904     7.244228      7

关键问题是:

  1. 如@r-beginners 所述,dff = df.copyy() 中有错字,应替换为 dff = df.copy()

  2. 您在布局中定义的下拉列表的 ID 是 'grade-selector',但在回调中您使用的是 'grade_selector'

  3. 下拉列表的样式 属性 定义不正确,因为它需要是字典,即您需要将 {'width', '40%'} 替换为 {'width': '40%'}

  4. 您正在使用 'view' 列来定义图表的色标,但不清楚您的数据框中是否真的有此列(它不包含在 df 显示在你上面的问题中)。

这些问题已在以下代码中修复:

import pandas as pd
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.express as px

# data
df = pd.DataFrame({
    'price': {0: 13.180632, 1: 13.515081, 2: 13.345507, 3: 13.296317, 4: 13.091904},
    'sqft_living': {0: 7.501082, 1: 8.384804, 2: 7.306531, 3: 7.319865, 4: 7.244228},
    'grade': {0: 7, 1: 8, 2: 7, 3: 7, 4: 7}
})

# app set-up
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

# app layout
app.layout = html.Div([

    html.H1('King County Housing Data: 1900-2015', style={'text-align': 'center'}),

    dcc.Dropdown(id='grade-selector',
                 options=[{'label': i, 'value': i} for i in df['grade'].unique()],
                 value=7,
                 multi=False,
                 style={'width': '40%'}),

    html.Div(id='output-container'),

    dcc.Graph(id='grade-price')

])

# app callbacks
@app.callback(
    [Output(component_id='output-container', component_property='children'),
     Output(component_id='grade-price', component_property='figure')],
    [Input(component_id='grade-selector', component_property='value')]
)

def gupdate_output_div(grade_selector):

    container = 'The grade the user selected was {}'.format(grade_selector)

    dff = df.copy()
    dff = dff[dff['grade'] == grade_selector]

    fig = px.scatter(dff, x='sqft_living', y='price', marginal_y='violin', marginal_x='box', trendline='ols', template='plotly_dark')

    return [container, fig]

if __name__ == '__main__':
    app.run_server(debug=False, host='127.0.0.1')