Related
I have a dash with 8 drop down lists, they work by pair meaning that for a drop-down list I can select ['EUR','USD','GBP', ''] and the associated drop-down list displays the value associated with the currency I mentioned.
Example: if I select 'EUR' in the first dropdown list, I will be offered some options (eur_ticker) in the associated dropdown list.
But, in the case I select '' in the first dropdown list, I want to the second dropdown list not to display any options but that its value is automatically set as [''].
(For the moment, I am proposing with only option [''] and I need to select it which is not user friendly).
Here is part of my code.
Does multiple outputs work in dash? How to work with it?
ccy_bond['EUR'] = eur_ticker
ccy_bond['USD'] = usd_ticker
ccy_bond['GBP'] = gbp_ticker
ccy_bond[''] = ['']
dbc.Col(['TRADE 1',
dbc.Col('Pay'),
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='dd-ccy-1s-id',
options=[
{'label': i, 'value': i} for i in ccy
],
value='EUR',
clearable=False,
),
], xs=12, sm=12, md=12, lg=3, xl=3),
dbc.Col([
dcc.Dropdown(
id='dd-bond-1s-id',
options=[
{'label': i, 'value': i} for i in eur_ticker
],
value=eur_ticker[4],
clearable=False,
)
], xs=12, sm=12, md=12, lg=9, xl=9),
]),
dbc.Col('Receive'),
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='dd-ccy-1b-id',
options=[
{'label': i, 'value': i} for i in ccy
],
value='EUR',
clearable=False,
),
], xs=12, sm=12, md=12, lg=3, xl=3),
dbc.Col([
dcc.Dropdown(
id='dd-bond-1b-id',
options=[
{'label': i, 'value': i} for i in eur_ticker
],
value=eur_ticker[9],
clearable=False,
)
], xs=12, sm=12, md=12, lg=9, xl=9),
]),
dbc.Col(id="graph1-trade1-id"),
dbc.Col(id="graph2-trade1-id")
], xs=12, sm=12, md=12, lg=4, xl=4),
# trade 1 - pay
#app.callback(
[
Output("dd-bond-1s-id", "options"),
],
[
Input("dd-ccy-1s-id", "value"),
]
)
def dd_update(ccy):
res = [
{'label': i, 'value': i} for i in ccy_bond[ccy]
],
return res
# trade 1 - receive
#app.callback(
[
Output("dd-bond-1b-id", "options"),
],
[
Input("dd-ccy-1b-id", "value"),
]
)
def dd_update2(ccy):
res = [
{'label': i, 'value': i} for i in ccy_bond[ccy]
],
return res
Yes, you are allowed to have multiple outputs in the same callback. So you could set options and value at the same time, such as in:
#app.callback(
[
Output("dd-bond-1s-id", "options"),
Output("dd-bond-1s-id", "value"),
],
[
Input("dd-ccy-1s-id", "value"),
]
)
def dd_update(ccy):
res = [
{'label': i, 'value': i} for i in ccy_bond[ccy]
]
value = res[0]["value"] # For simplicity
return res, value
As for the empty selection "", I would add a third output with the property "disabled" and return True if the selection is made. This way you prevent people from selecting other values.
I'm trying to develop a Dash application in python. I tried adding style={'display': 'inline-block'} to the html.Div() component, as well as to other components, but couldn't set the drop-down menus to align in one row.
The page looks as follows:
with the inline styling:
Without the inline styling:
The code in the question was given to me as a template that needs to be filled properly. The complex hierarchy was part of the template. My job is to add code as needed. I'm adding only the problematic part of the code (without the title and the graph elements that are seen in the images):
df = pd.read_csv("dash\Pricing Data.csv")
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
boxplot_layout = (
dbc.Container(
[dbc.Row(
[
dbc.Col(
[
dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.Div(
dbc.Row(
[
dbc.Col(
[
dcc.Dropdown(
id="aggregate-dropdown",
options=[
{
"label": "Total",
"value": "sum",
},
{
"label": "Average",
"value": "average",
},
],
value="sum",
style={
'textAlign': 'center',
# 'color': colors['text']
},
)
],
),
dbc.Col(
[
dcc.Dropdown(
id="y-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
],
),
dbc.Col(
[
html.Label(
"by",
style={
'textAlign': 'center',
# 'color': colors['text']
}
)
],
),
dbc.Col(
[
dcc.Dropdown(
id="x-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
'padding': '3px ',
},
value='Age'
)],),],)))],),])],inverse=True,)])])]))
app.layout = boxplot_layout
if __name__ == "__main__":
app.run_server(debug=True)
Also, as can be seen in the images, there's an error message. I couldn't find solutions for this error, so if you have any ideas regarding its cause or how to find it I'll be grateful if you could post it too.
Thanks.
Following the doc example:
dbc.Row(
[
dbc.Col(html.Div("One of three columns")),
dbc.Col(html.Div("One of three columns")),
dbc.Col(html.Div("One of three columns")),
]
),
it results something you are chasing for. So, that's the basic structure, removing unnecessary code, follows:
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import pandas as pd
df = pd.read_csv()
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
dbc.Container([
dbc.Row([
dbc.Col(
html.Div([
dcc.Dropdown(
id="aggregate-dropdown",
options=[
{
"label": "Total",
"value": "sum",
},
{
"label": "Average",
"value": "average",
},
],
value="sum",
style={
'textAlign': 'center',
# 'color': colors['text']
},
)
]), width=3
),
dbc.Col(
html.Div([
dcc.Dropdown(
id="y-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
]), width=3
),
dbc.Col(
html.Div([
html.Label(
"by",
style={
'textAlign': 'center',
# 'color': colors['text']
}
)
]), width=1
),
dbc.Col(
html.Div([
dcc.Dropdown(
id="x-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
]), width=3
),
])
])
])
if __name__ == "__main__":
app.run_server(debug=True)
Note I passed a 'width=' keyword argument to set the size of columns.
And that's the result:
result
I hope it's that help you to find the better way to organize your code.
What I did eventually was to change the style inside the Column components of the Drop-down menus, as well as the style of the Drop-down themselves. I used the tags 'padding' and 'width' and changed their values until it looked OK. I also used the value 'inline-block' for the 'display' tag.
For instance, here's the code for one of the drop-down menus and it's column:
dbc.Col(
[
dcc.Dropdown(
id="y-axis-dropdown",
options=
[{'label': i, 'value': i} for i in df.columns],
value='Age',
style={'textAlign': 'center'}
)
], style={
'display': 'inline-block',
'width': '25%',
'padding': 30,
'textAlign': 'center'
}
)
I tried now for some time to divide my dashboard into two columns, with "Material1" centered in the first column, and "Material2" centered in the second column, keeping the graph as is (entire width) of this dashboard:
I tried dbc.col and dbc.Row methods to solve this, but haven't found the right way to do this.
Any help is highly appreciated!! :)
This is my code:
app.layout = html.Div([
# Input Row: Material 1
html.Div([
html.Label('Material 1'),
dcc.Dropdown(
id='dropdown1',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-1',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
]),
# Input Row: Material 2
html.Div([
html.Label('Material 2'),
dcc.Dropdown(
id='dropdown2',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-2',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
], style={'display': 'inline-block'}),
# Input: Indicator
html.Div([
html.Label('Indicator'),
dcc.Dropdown(
id='dropdown3',
style={'width': '400px', 'margin-left': 0}),
]),
#Graph
html.Div([
dcc.Graph(
id='display-selected-values',
style={'width': '2400px', 'margin-left': 0, 'columnCount': 1}),
])
])
it's all about being systematic (where code formatters help)
using dash 2.0.0 and dbc 1.0.0-b1
keep on embedding Row and Col as required to meet your layout requirements
import json
import numpy as np
import dash_bootstrap_components as dbc
import dash
from jupyter_dash import JupyterDash
all_options = {k: v for k, v in zip(list("ABCD"), np.random.randint(1, 4, 4))}
options1 = list(all_options.keys())
# Build App
app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dash.html.Div(
[
dbc.Row(
[
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 1"),
dash.dcc.Dropdown(
id="dropdown1",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 2"),
dash.dcc.Dropdown(
id="dropdown2",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
],
justify="center",
),
dash.dcc.Graph(id="newCases", style={"height": "45vh"}),
],
style={"font-family": "Arial", "font-size": "0.9em", "text-align": "center"},
)
# Run app and display result inline in the notebook
app.run_server(mode="inline")
I have a probably simple problem that I cannot solve. I have two columns in my Python Dash dashboard, which are not aligned in height, see here:
What do I need to change in my code so that the two columns are on the same height?
Any help is much appreciated.
This is my code:
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([
html.Label('Material 1'),
dcc.Dropdown(
id='s1m1s',
options=[{'label': i, 'value': i} for i in available_indicators],
value=options1[0],
),
html.Label('Material 1'),
dcc.Dropdown(
id='s1mdf45',
options=[{'label': i, 'value': i} for i in available_indicators],
value=options1[0],
),
], style={'width': '20%', 'display': 'inline-block'}),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='s2m1_num',
min=0,
max=200,
value=0,
),
html.Label('m3'),
daq.NumericInput(
id='s2m2_num',
min=0,
max=200,
value=0,
),
], style={'width': '20%', 'display': 'inline-block'})
])
You can add 'vertical-align': 'top' to the style dictionaries of the two columns to make sure that they are aligned at the top, see below.
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_daq as daq
app = dash.Dash(__name__)
app.layout = html.Div([
# first column
html.Div(
children=[
html.Label('Material 1'),
dcc.Dropdown(
id='s1m1s',
options=[{'label': i, 'value': i} for i in ['option_1', 'option_2', 'option_3']],
value='option_1',
),
html.Label('Material 1'),
dcc.Dropdown(
id='s1mdf45',
options=[{'label': i, 'value': i} for i in ['option_1', 'option_2', 'option_3']],
value='option_2',
),
],
style={
'width': '20%',
'display': 'inline-block',
'vertical-align': 'top',
}
),
# second column
html.Div(
children=[
html.Label('m3'),
daq.NumericInput(
id='s2m1_num',
min=0,
max=200,
value=0,
),
html.Label('m3'),
daq.NumericInput(
id='s2m2_num',
min=0,
max=200,
value=0,
),
],
style={
'width': '20%',
'display': 'inline-block',
'vertical-align': 'top',
}
)
])
if __name__ == '__main__':
app.run_server(debug=True, host='127.0.0.1')
I am trying to create a layout using the DASH app, and I am not sure why it's not working when I am trying to set the input boxes with a drop-down.
here is my layout:
tab_1_layout = html.Div([
dcc.Input(id="ad_account_id", type="text", placeholder="Account ID", style={'width': '200px',
'margin-top': 10,
'margin-left': 20,
}),
# html.Br(),
dcc.Input(id="app_id", type="text", placeholder="App ID", style={'width': '200px',
'margin-left': 20,
'display': 'inline-block'
}),
# html.Br(),
dcc.Input(id="access_token", type="text", placeholder="Access Token", style={'width': '200px',
'margin-left': 20,
'display': 'inline-block'
}),
# html.Br(),
dcc.Input(id="app_secret", type="text", placeholder="App Secret", style={'width': '200px',
'margin-left': 20,
}),
# html.Br(),
dcc.Dropdown(
id='dimensions',
options=[{'label': i, 'value': i} for i in ['Campaign', 'Placement', 'Creative']],
multi=True,
placeholder='Dimensions',
style={'width': '200px', 'margin-left': 150, 'margin-top': 20, 'display':'inline-block'}
),
# html.Br(),
dcc.Dropdown(
id='metrics',
options=[{'label': i, 'value': i} for i in ['Impressions', 'Clicks', 'Conversions']],
multi=True,
placeholder='Metrics',
style={'width': '200px', 'margin-left': 400}
),
html.Br(),
dcc.DatePickerSingle(
id='start-date',
placeholder="Start Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '200px', 'margin-top': 10, 'margin-left': 400}
),
# html.Br(),
dcc.DatePickerSingle(
id='end-date',
placeholder="End Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '200px', 'margin-top': 10, 'margin-left': 220}
),
html.Br(),
html.Button(id='submit-button', type='submit', children='Submit', style={'width': '200px', 'margin-top': 10,
'margin-left': 10}),
html.Div(id='output_div')]),
its shwoing the UI like below but i want to align dimension and metrics with first row and then on second row align start date and end date and third row will be submit.
There are a number of ways to achieve this but personally I like Dash Bootstrap layout. Below is your code refactored to use bootstrap rows and columns to achieve what you want. Bootstrap layout
import datetime
import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import dash_html_components as html
import numpy as np
app = dash.Dash(external_stylesheets = [dbc.themes.BOOTSTRAP])
app.title = "Steepest Descent"
server = app.server
row1 = html.Div(
[
dbc.Row([
dbc.Col([
dbc.Input(id="ad_account_id",
type="text",
placeholder="Account ID",
style={'width': '150px'}),
], width={"order": "first"}),
dbc.Col([
dbc.Input(id="app_id",
type="text",
placeholder="App ID",
style={'width': '150px'}),
]),
dbc.Col([
dbc.Input(id="access_token",
type="text",
style={'width': '150px'},
placeholder="Access Token")
]),
dbc.Col([
dbc.Input(id="app_secret",
type="text",
style={'width': '150px'},
placeholder="App Secret")
]),
dbc.Col([
dcc.Dropdown(
id='dimensions',
options=[{'label': i, 'value': i} for i in ['Campaign', 'Placement', 'Creative']],
multi=True,
style={'width': '150px'},
placeholder='Dimensions')
]),
dbc.Col([
dcc.Dropdown(
id='metrics',
options=[{'label': i, 'value': i} for i in ['Impressions', 'Clicks', 'Conversions']],
multi=True,
style={'width': '150px'},
placeholder='Metrics')
])
], align="center"),
]
)
row2 = html.Div([
dbc.Row([
dbc.Col([
dcc.DatePickerSingle(
id='start-date',
placeholder="Start Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '150px'}
),
], width={"order": "first"}),
dbc.Col([
# html.Br(),
dcc.DatePickerSingle(
id='end-date',
placeholder="End Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '150px'}
)], align="center"),
])
])
row3 = html.Div([
dbc.Row([
dbc.Col([
html.Button(id='submit-button', type='submit', children='Submit', style={'width': '200px', 'margin-top': 10,
'margin-left': 10}),
], width={"order": "first"}),
dbc.Col([
html.Div(id='output_div'),
])
])
])
app.layout = dbc.Container(children=[
row1,
html.Br(),
row2,
html.Br(),
row3]
)
if __name__ == '__main__':
app.run_server(debug=True)