【问题标题】:Graph is not being returned by Plotly Dash CallbackPlotly Dash 回调未返回图表
【发布时间】:2021-11-15 17:44:39
【问题描述】:

我正在做一些 GIS 分析,有点慌张。

我需要创建一个交互式绘图仪表板应用程序,其中您有两个多下拉仪表板核心组件,它们更新 px.scatter_mapbox 地图上的值。 DataFrame 在下拉列表中有以下我需要的“过滤器”/字段:种族/民族和城市。我被困在这一点上:

  1. 点击 Race Drop down (Multi) (works)
  2. 城市选项已适当填写(有效)
  3. 地图不会更新 - 只会返回您在下面看到的内容。

这是我的代码:

import dash.dependencies
import plotly.express as px
import pandas as pd
from jupyter_dash import JupyterDash
import dash_core_components as dcc
from dash import html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
px.set_mapbox_access_token(mapbox_access_token)

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

app = JupyterDash(__name__, external_stylesheets=external_stylesheets)

re_indicators = df["RE"].unique()

city_indicators = df["CITY"].unique()

app.layout = html.Div([
    html.Div(children=[
        html.Label('Race & Ethnicity'),
        dcc.Dropdown( id = "re",
                     options=[{'label': i, 'value': i} for i in re_indicators],
                     value = ["White"], 
                     multi = True
                     ), 
        html.Label('City'),
        dcc.Dropdown( id = "city",
                     options=[], 
                     value = [],
                     multi = True
                     ),        
    html.Div([
        dcc.Graph(
            id='my_map',
            figure = {})
    ])
    ])])


@app.callback(
    dash.dependencies.Output('city', 'options'),
    dash.dependencies.Input('re', 'value')
)
def re_picker(choose_re):
  
  if len(choose_re) > 0: 
    
    dff = df[df.RE.isin(choose_re)]

  return [{'label': i, 'value': i} for i in (dff.CITY.unique())]

@app.callback(
    dash.dependencies.Output('city', 'value'),
    dash.dependencies.Input('city', 'options')
)
def set_city_value(available_options): 
  return [x['value'] for x in available_options]

@app.callback(
    dash.dependencies.Output('my_map', 'figure'),
    [dash.dependencies.Input('re', 'value'),
    dash.dependencies.Input('city', 'value')]
)
def update_figure(selected_re, selected_city): 
  if len(selected_re) == 0:
    return print("nope")
  else:
    df_filtered = dff[(dff['CITY'] == selected_city)]
    fig = px.scatter_mapbox(df_filtered,
                            lat="Latitude",
                            lon="Longitude",
                            zoom=1)
    return fig

# Run app and display result inline in the notebook
if __name__ == '__main__':
    app.run_server(host = "127.0.0.1", port = "8888", mode= "inline", debug = False)

Ouput Photo

【问题讨论】:

  • 由于您没有共享数据,我无法完全重现该问题,但我猜该错误来自这一行:dff['CITY'] == selected_city。尝试用dff['CITY'] .isin(selected_city) 替换它。请注意,selected_city 是一个列表,因为它是一个多下拉列表的值。
  • 真的需要一些样本数据,我可以在 kaggle 上按国家/地区找到人口统计数据,但按城市却找不到

标签: python plotly-dash plotly-python


【解决方案1】:
  • 您没有提供任何数据,已经生成了一些示例数据
  • 您的代码存在一些问题。所有实际上都会产生明显的异常
    1. 范围,dff 是所有 回调 的注释范围,但是您假设它是。修复仅将 df 作为全局范围
    2. list 平等毫无意义。使用isin()
    3. 如果不满足回调的条件,更好的做法是使用raise dash.exceptions.PreventUpdate

解决方案

import dash.dependencies
import plotly.express as px
import pandas as pd
from jupyter_dash import JupyterDash
import dash_core_components as dcc
from dash import html
from dash.dependencies import Input, Output
import plotly.graph_objects as go

# px.set_mapbox_access_token(mapbox_access_token)

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)

re_indicators = df["RE"].unique()
city_indicators = df["CITY"].unique()

app.layout = html.Div(
    [
        html.Div(
            children=[
                html.Label("Race & Ethnicity"),
                dcc.Dropdown(
                    id="re",
                    options=[{"label": i, "value": i} for i in re_indicators],
                    value=["White"],
                    multi=True,
                ),
                html.Label("City"),
                dcc.Dropdown(id="city", options=[], value=[], multi=True),
                html.Div([dcc.Graph(id="my_map", figure={})]),
            ]
        )
    ]
)


@app.callback(
    dash.dependencies.Output("city", "options"), dash.dependencies.Input("re", "value")
)
def re_picker(choose_re):
    if len(choose_re) > 0:
        dff = df[df.RE.isin(choose_re)]
    else:
        raise dash.exceptions.PreventUpdate

    return [{"label": i, "value": i} for i in (dff.CITY.unique())]


@app.callback(
    dash.dependencies.Output("city", "value"),
    dash.dependencies.Input("city", "options"),
)
def set_city_value(available_options):
    return [x["value"] for x in available_options]


@app.callback(
    dash.dependencies.Output("my_map", "figure"),
    [dash.dependencies.Input("re", "value"), dash.dependencies.Input("city", "value")],
)
def update_figure(selected_re, selected_city):
    if not selected_re or not selected_city or len(selected_re)==0 or len(selected_city)==0:
        raise dash.exceptions.PreventUpdate

    # df_filtered = dff[(dff['CITY'] == selected_city)] # this is out of scope!!!
    df_filtered = df.loc[df["CITY"].isin(selected_city) & df["RE"].isin(selected_re)]
    fig = px.scatter_mapbox(df_filtered, lat="Latitude", lon="Longitude", zoom=1).update_layout(mapbox={"style":"carto-positron"})
    return fig


# Run app and display result inline in the notebook
if __name__ == "__main__":
    app.run_server(host="127.0.0.1", port="8888", mode="inline", debug=False)

数据

import io
import pandas as pd

df = pd.read_csv(io.StringIO("""RE,Longitude,Latitude,CITY
Black,-120.99774156574261,37.559165406261,Stanislaus
Pacific,-120.65111562736087,38.446389516422855,Amador
Pacific,-119.81550247702623,36.07536100517565,Kings
Black,-121.95120685287338,37.92342159137978,Contra Costa
Native,-118.26100262413676,34.197992401614535,Los Angeles
Asian,-120.7249673888429,41.58984787469562,Modoc
White,-121.95120685287338,37.92342159137978,Contra Costa
Hispanic,-123.9578138104391,41.74495737627584,Del Norte
Black,-122.39220680431815,39.59840477506362,Glenn
Pacific,-122.04052155027398,40.7637665910163,Shasta
Black,-120.71766862423333,37.19185694553567,Merced
Native,-121.69484223375345,39.03452277403378,Sutter
Black,-115.9938588669452,33.743676039870444,Riverside
Black,-119.90551726806129,37.58152187924647,Mariposa
Pacific,-117.41078970333236,36.51112681410214,Inyo
Black,-119.76264585146096,37.218035870388235,Madera
Pacific,-123.43155392039253,39.433623844726505,Mendocino
Black,-121.34428014540734,38.4493728777556,Sacramento
White,-120.7249673888429,41.58984787469562,Modoc
Pacific,-119.64932124370894,36.758179506828185,Fresno
White,-119.81550247702623,36.07536100517565,Kings
Native,-121.91788591709779,37.65054956250571,Alameda
Asian,-121.07499558470187,36.6057059207284,San Benito
Native,-120.52464692805631,38.778737966889466,El Dorado
Pacific,-120.55413218695809,38.204606401638536,Calaveras
Hispanic,-116.17845588321354,34.84143467938159,San Bernardino
Black,-122.23388486629841,40.12573617303074,Tehama
White,-121.90162044594241,38.68664649354098,Yolo
Native,-120.45219691432906,35.38741552944272,San Luis Obispo
Pacific,-119.82065303166894,38.59725063024503,Alpine"""))

【讨论】:

猜你喜欢
  • 2020-03-07
  • 2020-03-17
  • 2021-09-10
  • 2021-06-07
  • 2021-05-22
  • 2020-02-15
  • 2022-09-29
  • 1970-01-01
  • 2021-08-13
相关资源
最近更新 更多