Dash 应用程序没有错误,但没有绘图
Dash app has no errors, but does not plot
我有一些长而复杂的代码似乎可以正确执行,但没有在绘制。这是怎么回事?
正在绘制的数据是一个嵌套字典,字典中的每个键对应一个下拉选项。这是一些核心代码:
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from pandas import Timestamp
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import numpy as np
from datetime import timedelta
import glob
import datetime as dt
Edit3:我修复了回调问题并能够从 dcc.Store 加载数据,这只是一个日期对象。现在,我使用该日期对象加载并格式化我的数据,结果为 final_dict
。但是,之后数据仍然不想用我的代码绘制。
我很困惑为什么这不起作用。
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
controls = dbc.Card(
[dcc.Store(id='date_output'),
dbc.FormGroup([
dcc.DatePickerSingle(
id='my-date-picker-single',
min_date_allowed=dt.date(2018, 4, 17),
max_date_allowed=dt.date(2020, 10, 6),
initial_visible_month=dt.date(2020, 10, 6),
date=dt.date(2020, 10, 6)
),
],
),
dbc.FormGroup(
dcc.RadioItems(
id='hour_radio',
options=[{'label': '00z', 'value': '00z'},
{'label': '12z', 'value': '12z'}],
value='00z',
labelStyle={'display': 'inline-block'},
inputStyle={"margin-left": "15px","margin-right": "5px"}
),
),
dbc.FormGroup(
[dbc.Label("Model"),
dcc.Dropdown(
id='model_dd',
options=[{'label': k, 'value': k} for k in model_list],
value=model_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Crop"),
dcc.Dropdown(
id='crop_dd',
options=[{'label': i.title(), 'value': i} for i in crop_list],
value=crop_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Weighting"),
dcc.Dropdown(
id='weight_dd',
options=[{'label': i, 'value': i} for i in weight_list],
value=weight_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Forecast Variable"),
dcc.Dropdown(
id='columns_dd',
options=[{'label': i, 'value': i} for i in column_list],
value=column_list[0],
clearable=False
),
]
),
dbc.FormGroup(
dcc.RadioItems(
id='units_radio',
options=[{'label': 'Metric', 'value': 'Metric'},
{'label': 'Imperial', 'value': 'Imperial'}],
value='Metric',
labelStyle={'display': 'inline-block'},
inputStyle={"margin-left": "20px","margin-right": "5px"}
),
),
],
body=True,
)
app.layout = dbc.Container(
[
html.Hr(),
dbc.Row([
dbc.Col([
dbc.Row([
dbc.Col(controls)
], align="start"),
],xs = 2)
,
dbc.Col([
dbc.Row([
dbc.Col([html.Div(id = 'plot_title')],)
]),
dbc.Row([
dbc.Col(dcc.Graph(id="crop-graph")),
]),
dbc.Row([
dbc.Col([html.Div(id = 'date_picker')],)
]),
])
],),
],
fluid=True,
)
@app.callback(
Output('date_output', 'data'),
[Input('my-date-picker-single', 'date'),
Input('hour_radio', 'value')])
def update_output(data, radio2):
if radio2=='00z':
data = pd.to_datetime(data)
elif radio2=='12z':
data = pd.to_datetime(data)
data=data+dt.timedelta(hours=12)
return data
@app.callback(
Output('crop-graph', 'figure'),
[Input('model_dd', 'value'),
Input('weight_dd', 'value'),
Input('crop_dd', 'value'),
Input('columns_dd', 'value'),
Input('units_radio', 'value'),
Input('date_output', 'data')])
def make_graph(model, weight, available_crops, vals, radio, data):
#do data formatting here, and end up with final_dict
if radio=='Metric':
if weight == 'Production':
df_delta_prod_temp = pd.concat([final_dict[model][weight][available_crops]['time'], final_dict[model][weight][available_crops]['24h Delta Temp']], axis=1).set_index('time').resample('24h').mean().reset_index()
df_delta_prod_precip = pd.concat([final_dict[model][weight][available_crops]['time'], final_dict[model][weight][available_crops]['24h Delta Precip']], axis=1).set_index('time').resample('24h').mean().reset_index()
if vals=='Temperature':
fig.add_trace(go.Scatter(x=final_dict[model][weight][available_crops]['time'], y=final_dict[model][weight][available_crops][vals]-273,
mode = 'lines', line=dict(color='red', width=4),
hovertemplate='Date: %{x|%d %b %H%M} UTC<br>Temp: %{y:.2f} C<extra></extra>'), secondary_y=True)
fig.add_trace(go.Bar(x=df_delta_prod_temp['time']['time'],
y=df_delta_prod_temp['24h Delta Temp'],
marker_color = "white", opacity=1,hovertemplate='Date: %{x|%d %b}<br>Delta: %{y:.2f} C<extra></extra>'),
secondary_y=False)
fig.update_yaxes(title_text="<b>Temp (C)<b>", color='red', secondary_y=True)
fig.update_yaxes(title_text="<b>24hr Forecast Change (C)</b>", secondary_y=False)
print(fig)
return fig
app.run_server(mode='external', port = 4100, debug=True)
final_dict
的形式为 final_dict[model_key][weight_keys][crop_key][value_key][dataframe]
我收到此错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
这是在行 if vals=='Temperature'
上触发的。我在这里使用 if 语句,以便我可以正确地格式化绘图(正如您在 plot 命令后面的行中看到的那样),因为 3 个变量(温度、总降水量和总雪量)的绘图都将不同。我怎样才能解决这个问题?这是嵌套字典末尾数据框的打印结果:
24h Delta Temp Temperature Total Snow 24h Delta Precip Total Precip \
0 0.498935 290.315356 NaN NaN NaN
1 0.237127 285.985779 0.000000 0.000866 0.006311
2 0.328559 283.643185 0.000000 0.003557 0.013087
3 0.749757 295.701362 0.000000 0.006307 0.015658
4 0.888228 293.332520 0.000000 -0.000009 0.005487
.. ... ... ... ... ...
56 -2.917237 285.034693 0.009300 0.161451 0.523343
57 NaN 281.955112 0.010279 NaN 0.729168
58 NaN 280.365132 0.013355 NaN 0.605418
59 NaN 287.087138 0.012851 NaN 0.522774
60 NaN 284.684470 0.006231 NaN 0.459217
time
0 2020-10-06 00:00:00
1 2020-10-06 06:00:00
2 2020-10-06 12:00:00
3 2020-10-06 18:00:00
4 2020-10-07 00:00:00
.. ...
56 2020-10-20 00:00:00
57 2020-10-20 06:00:00
58 2020-10-20 12:00:00
59 2020-10-20 18:00:00
60 2020-10-21 00:00:00
你永远不会定义final_dict
编辑:更新答案和代码示例以回应进一步的讨论
@app.callback(
Output('date_output', 'data'),
[Input('my-date-picker-single', 'date'),
Input('hour_radio', 'value')])
def update_output(date_value, radio2):
final_dict = {
'tempurature': {0: 1, 1: 5, 2: 3, 3: 5, 4: 1, 5: 2, 6: 5, 7: 6},
# and so on
}
return final_dict
这个函数需要定义那个变量,否则它只会return None
。也要小心你的缩进,因为设置的方式会阻止第二个 if
语句的执行,并且总是 return 在第一个 return
语句。
此外,你不需要括号,你可以只做 return final_dict
。
你的第二个回调,它输出到图中,正确地从 dcc.Store
中获取数据,但你从来没有使用它。 Input
对应于您在回调函数签名中定义的 data
arg。您应该将该函数中 final_dict
的使用替换为 data
.
我有一些长而复杂的代码似乎可以正确执行,但没有在绘制。这是怎么回事?
正在绘制的数据是一个嵌套字典,字典中的每个键对应一个下拉选项。这是一些核心代码:
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from pandas import Timestamp
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import numpy as np
from datetime import timedelta
import glob
import datetime as dt
Edit3:我修复了回调问题并能够从 dcc.Store 加载数据,这只是一个日期对象。现在,我使用该日期对象加载并格式化我的数据,结果为 final_dict
。但是,之后数据仍然不想用我的代码绘制。
我很困惑为什么这不起作用。
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
controls = dbc.Card(
[dcc.Store(id='date_output'),
dbc.FormGroup([
dcc.DatePickerSingle(
id='my-date-picker-single',
min_date_allowed=dt.date(2018, 4, 17),
max_date_allowed=dt.date(2020, 10, 6),
initial_visible_month=dt.date(2020, 10, 6),
date=dt.date(2020, 10, 6)
),
],
),
dbc.FormGroup(
dcc.RadioItems(
id='hour_radio',
options=[{'label': '00z', 'value': '00z'},
{'label': '12z', 'value': '12z'}],
value='00z',
labelStyle={'display': 'inline-block'},
inputStyle={"margin-left": "15px","margin-right": "5px"}
),
),
dbc.FormGroup(
[dbc.Label("Model"),
dcc.Dropdown(
id='model_dd',
options=[{'label': k, 'value': k} for k in model_list],
value=model_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Crop"),
dcc.Dropdown(
id='crop_dd',
options=[{'label': i.title(), 'value': i} for i in crop_list],
value=crop_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Weighting"),
dcc.Dropdown(
id='weight_dd',
options=[{'label': i, 'value': i} for i in weight_list],
value=weight_list[0],
clearable=False
),
]
),
dbc.FormGroup(
[dbc.Label("Forecast Variable"),
dcc.Dropdown(
id='columns_dd',
options=[{'label': i, 'value': i} for i in column_list],
value=column_list[0],
clearable=False
),
]
),
dbc.FormGroup(
dcc.RadioItems(
id='units_radio',
options=[{'label': 'Metric', 'value': 'Metric'},
{'label': 'Imperial', 'value': 'Imperial'}],
value='Metric',
labelStyle={'display': 'inline-block'},
inputStyle={"margin-left": "20px","margin-right": "5px"}
),
),
],
body=True,
)
app.layout = dbc.Container(
[
html.Hr(),
dbc.Row([
dbc.Col([
dbc.Row([
dbc.Col(controls)
], align="start"),
],xs = 2)
,
dbc.Col([
dbc.Row([
dbc.Col([html.Div(id = 'plot_title')],)
]),
dbc.Row([
dbc.Col(dcc.Graph(id="crop-graph")),
]),
dbc.Row([
dbc.Col([html.Div(id = 'date_picker')],)
]),
])
],),
],
fluid=True,
)
@app.callback(
Output('date_output', 'data'),
[Input('my-date-picker-single', 'date'),
Input('hour_radio', 'value')])
def update_output(data, radio2):
if radio2=='00z':
data = pd.to_datetime(data)
elif radio2=='12z':
data = pd.to_datetime(data)
data=data+dt.timedelta(hours=12)
return data
@app.callback(
Output('crop-graph', 'figure'),
[Input('model_dd', 'value'),
Input('weight_dd', 'value'),
Input('crop_dd', 'value'),
Input('columns_dd', 'value'),
Input('units_radio', 'value'),
Input('date_output', 'data')])
def make_graph(model, weight, available_crops, vals, radio, data):
#do data formatting here, and end up with final_dict
if radio=='Metric':
if weight == 'Production':
df_delta_prod_temp = pd.concat([final_dict[model][weight][available_crops]['time'], final_dict[model][weight][available_crops]['24h Delta Temp']], axis=1).set_index('time').resample('24h').mean().reset_index()
df_delta_prod_precip = pd.concat([final_dict[model][weight][available_crops]['time'], final_dict[model][weight][available_crops]['24h Delta Precip']], axis=1).set_index('time').resample('24h').mean().reset_index()
if vals=='Temperature':
fig.add_trace(go.Scatter(x=final_dict[model][weight][available_crops]['time'], y=final_dict[model][weight][available_crops][vals]-273,
mode = 'lines', line=dict(color='red', width=4),
hovertemplate='Date: %{x|%d %b %H%M} UTC<br>Temp: %{y:.2f} C<extra></extra>'), secondary_y=True)
fig.add_trace(go.Bar(x=df_delta_prod_temp['time']['time'],
y=df_delta_prod_temp['24h Delta Temp'],
marker_color = "white", opacity=1,hovertemplate='Date: %{x|%d %b}<br>Delta: %{y:.2f} C<extra></extra>'),
secondary_y=False)
fig.update_yaxes(title_text="<b>Temp (C)<b>", color='red', secondary_y=True)
fig.update_yaxes(title_text="<b>24hr Forecast Change (C)</b>", secondary_y=False)
print(fig)
return fig
app.run_server(mode='external', port = 4100, debug=True)
final_dict
的形式为 final_dict[model_key][weight_keys][crop_key][value_key][dataframe]
我收到此错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
这是在行 if vals=='Temperature'
上触发的。我在这里使用 if 语句,以便我可以正确地格式化绘图(正如您在 plot 命令后面的行中看到的那样),因为 3 个变量(温度、总降水量和总雪量)的绘图都将不同。我怎样才能解决这个问题?这是嵌套字典末尾数据框的打印结果:
24h Delta Temp Temperature Total Snow 24h Delta Precip Total Precip \
0 0.498935 290.315356 NaN NaN NaN
1 0.237127 285.985779 0.000000 0.000866 0.006311
2 0.328559 283.643185 0.000000 0.003557 0.013087
3 0.749757 295.701362 0.000000 0.006307 0.015658
4 0.888228 293.332520 0.000000 -0.000009 0.005487
.. ... ... ... ... ...
56 -2.917237 285.034693 0.009300 0.161451 0.523343
57 NaN 281.955112 0.010279 NaN 0.729168
58 NaN 280.365132 0.013355 NaN 0.605418
59 NaN 287.087138 0.012851 NaN 0.522774
60 NaN 284.684470 0.006231 NaN 0.459217
time
0 2020-10-06 00:00:00
1 2020-10-06 06:00:00
2 2020-10-06 12:00:00
3 2020-10-06 18:00:00
4 2020-10-07 00:00:00
.. ...
56 2020-10-20 00:00:00
57 2020-10-20 06:00:00
58 2020-10-20 12:00:00
59 2020-10-20 18:00:00
60 2020-10-21 00:00:00
你永远不会定义final_dict
编辑:更新答案和代码示例以回应进一步的讨论
@app.callback(
Output('date_output', 'data'),
[Input('my-date-picker-single', 'date'),
Input('hour_radio', 'value')])
def update_output(date_value, radio2):
final_dict = {
'tempurature': {0: 1, 1: 5, 2: 3, 3: 5, 4: 1, 5: 2, 6: 5, 7: 6},
# and so on
}
return final_dict
这个函数需要定义那个变量,否则它只会return None
。也要小心你的缩进,因为设置的方式会阻止第二个 if
语句的执行,并且总是 return 在第一个 return
语句。
此外,你不需要括号,你可以只做 return final_dict
。
你的第二个回调,它输出到图中,正确地从 dcc.Store
中获取数据,但你从来没有使用它。 Input
对应于您在回调函数签名中定义的 data
arg。您应该将该函数中 final_dict
的使用替换为 data
.