【发布时间】:2023-03-31 01:28:01
【问题描述】:
这个问题基本上是对这个先前提出的问题的补充:
Properly setting up callbacks for dynamic dropdowns plotly dash
现在,我想在我的绘图中添加第二条轨迹,它位于辅助 y 轴上。辅助 y 轴上的绘图数据将来自类似结构的字典和数据框,也具有类似的命名约定。这是我所拥有的。
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
index1= [1,2,3,4]
columns1 =['time', '2m_temp_prod' , 'total_precip_prod']
index2= [1,2,3,4]
columns2 = ['time', '2m_temp_area', 'total_precip_area']
df_vals_prod = {'corn': pd.DataFrame(index=index1, columns = columns1,
data= np.random.randn(len(index1),len(columns1))).cumsum(),
'soybeans' : pd.DataFrame(index=index1, columns = columns1,
data= np.random.randn(len(index1),len(columns1))).cumsum()}
df_vals_area= {'corn': pd.DataFrame(index=index2, columns = columns2,
data= np.random.randn(len(index2),len(columns2))).cumsum(),
'soybeans' : pd.DataFrame(index=index2, columns = columns2,
data= np.random.randn(len(index2),len(columns2))).cumsum()}
# mimic data properties of your real world data
df_vals_prod['corn']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_vals_prod['corn'].set_index('time', inplace = True)
df_vals_prod['soybeans']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_vals_prod['soybeans'].set_index('time', inplace = True)
df_vals_area['corn']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_vals_area['corn'].set_index('time', inplace = True)
df_vals_area['soybeans']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_vals_area['soybeans'].set_index('time', inplace = True)
index3= [1,2,3,4]
columns3 =['time', '2m_temp_24hdelta_prod' , 'total_precip_24hdelta_prod']
index4= [1,2,3,4]
columns4 = ['time', '2m_temp_24hdelta_area', 'total_precip_24hdelta_area']
df_deltas_prod = {'corn': pd.DataFrame(index=index3, columns = columns3,
data= np.random.randn(len(index3),len(columns3))).cumsum(),
'soybeans' : pd.DataFrame(index=index3, columns = columns3,
data= np.random.randn(len(index3),len(columns3))).cumsum()}
df_deltas_area= {'corn': pd.DataFrame(index=index4, columns = columns4,
data= np.random.randn(len(index4),len(columns4))).cumsum(),
'soybeans' : pd.DataFrame(index=index4, columns = columns4,
data= np.random.randn(len(index4),len(columns4))).cumsum()}
# mimic data properties of your real world data
df_deltas_prod['corn']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_deltas_prod['corn'].set_index('time', inplace = True)
df_deltas_prod['soybeans']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_deltas_prod['soybeans'].set_index('time', inplace = True)
df_deltas_area['corn']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_deltas_area['corn'].set_index('time', inplace = True)
df_deltas_area['soybeans']['time'] = [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
df_deltas_area['soybeans'].set_index('time', inplace = True)
# weighting
all_options = {
'Production': list(df_vals_prod[list(df_vals_prod.keys())[0]].columns[1:]),
'Area': list(df_vals_area[list(df_vals_prod.keys())[0]].columns[1:])
}
controls = dbc.Card(
[ dbc.FormGroup(
[
dbc.Label("Crop"),
dcc.Dropdown(
id='crop_dd',
options=[{'label': k.title(), 'value': k} for k in list(df_vals_prod.keys())],
value=list(df_vals_prod.keys())[0],
clearable=False,
),
]
),
dbc.FormGroup(
[
dbc.Label("Weighting"),
dcc.Dropdown(
id='weight_dd',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value='Area',
clearable=False,
),
]
),
dbc.FormGroup(
[
dbc.Label("Forecast Variable"),
dcc.Dropdown(
id='columns_dd',
clearable=False,
),
]
),
],
body=True,
)
app.layout = dbc.Container(
[
html.Hr(),
dbc.Row([
dbc.Col([
dbc.Row([
dbc.Col(controls)
], align="start"),
dbc.Row([
dbc.Col([
html.Br(),
dbc.Row([
dbc.Col([html.Div(id = 'txt1')
])
]),
html.Br(),
dbc.Row([
dbc.Col([html.Div(id = 'txt2')])
])
])
])
],xs = 2)
,
dbc.Col([
dbc.Row([
dbc.Col([html.Div(id = 'plot_title')],)
]),
dbc.Row([
dbc.Col(dcc.Graph(id="crop-graph")),
#dbc.Col(dcc.Graph(id="cluster-graph"))
])
])
],),
],
fluid=True,
)
# Callbacks #####################################################################
# Weighting selection.
@app.callback( # Dataframe PROD or AREA
Output('columns_dd', 'options'),
# layout element: dcc.RadioItems(id='weight_dd'...)
[Input('weight_dd', 'value')])
def set_columns_options(weight):
varz = [{'label': i, 'value': i} for i in all_options[weight]]
return [{'label': i, 'value': i} for i in all_options[weight]]
# Columns selection
@app.callback(
Output('columns_dd', 'value'),
[Input('columns_dd', 'options')])
def set_columns(available_options):
return available_options[1]['value']
# Crop selection
@app.callback(
Output('crop_dd', 'value'),
[Input('crop_dd', 'options')])
def set_crops(available_crops):
return available_crops[0]['value']
# Make a figure based on the selections
@app.callback( # Columns 2m_temp_prod, or....
Output('crop-graph', 'figure'),
[Input('weight_dd', 'value'),
Input('crop_dd', 'value'),
Input('columns_dd', 'value')])
def make_graph(weight, available_crops, vals):
# data source / weighting
if weight == 'Production':
dfv = df_vals_prod
#dfd = df_deltas_prod
if weight == 'Area':
dfv = df_vals_area
#dfd= df_deltas_area
# plotly figure
fig = make_subplots(specs=[[{"secondary_y": True}]])
if 'precip' in vals:
fig.add_trace(go.Scatter(x=df_vals_prod[available_crops]['time'], y=round((dfv[available_crops][vals].cumsum()/25.4),2),
mode = 'lines', line=dict(color='lime', width=4),
hovertemplate='Date: %{x|%d %b %H%M} UTC<br>Precip: %{y:.2f} in<extra></extra>'), secondary_y=False)
else:
fig.add_trace(go.Scatter(x=df_vals_prod[available_crops]['time'], y=round(((dfv[available_crops][vals]-273.15)*(9/5))+32,2),
mode = 'lines', line=dict(color='red', width=4),
hovertemplate='Date: %{x|%d %b %H%M} UTC<br>Temp: %{y:.2f} F<extra></extra>'), secondary_y=False)
#fig.add_trace(go.Bar(x=dfd[available_crops].index, y=dfd[available_crops][deltas]), secondary_y=True)
fig.update_layout(title=dict(text='Crop: ' + available_crops.title() + ', Weight: ' +weight+ ', Variable: '+ vals))
fig.update_layout(yaxis2_showgrid=False,showlegend=False,
width=1500,height=800,yaxis_zeroline=False, yaxis2_zeroline=False)
fig.update_layout(template="plotly_dark", plot_bgcolor='#272B30', paper_bgcolor='#272B30')
fig.update_yaxes(automargin=True)
return(fig)
app.run_server(mode='external', port = 8099)
注意字典名称和字典中的数据框列如何具有相似的名称。我希望他们在情节上保持在一起。
例如,用户选择权重:生产,作物:玉米,预测变量:2m_temp_prod。这应该绘制一个线图。现在,我想添加一个辅助 y 轴,其中 2m_temp_24hdelta_prod 被绘制(来自 df_deltas_prod['corn']['2m_temp_24hdelta_prod']。请注意,虽然我不想要一个下拉菜单,但我只是希望它是根据其他下拉选择绘制。最后,如果用户切换到权重:面积,作物:玉米,预测变量:2m_temp_area,次要 y 轴将绘制 df_deltas_area['corn']['2m_temp_24hdelta_area']。希望这个很清楚。
【问题讨论】:
-
你能在你的代码 sn-p 中包含你的导入吗?
标签: python plotly plotly-dash plotly-python