Automatically select checkbox Python and Dash - python

I have this python code working - If a user selects the "Select All" checkbox, all the checkboxes are selected/unselected.
I need the code to automatically check/uncheck the "Select All" checkbox if all the checkboxes are checked/unchecked.
Thank you! I used Google Collab
!pip install jupyter-dash
import plotly.express as px
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from dash.dependencies import Input, Output, State
# Build App
app = JupyterDash(__name__)
app.layout = html.Div(
[
dcc.Checklist(
id="all-or-none",
options=[{"label": "Select All", "value": "All"}],
value=[],
labelStyle={"display": "inline-block"},
),
dcc.Checklist(
id="my-checklist",
options=[
{"label": "New York City", "value": "NYC"},
{"label": "Montréal", "value": "MTL"},
{"label": "San Francisco", "value": "SF"},
],
value=[],
labelStyle={"display": "inline-block"},
),
]
)
#app.callback(
Output("my-checklist", "value"),
[Input("all-or-none", "value")],
[State("my-checklist", "options")],
)
def select_all_none(all_selected, options):
all_or_none = []
all_or_none = [option["value"] for option in options if all_selected]
return all_or_none
# Run app and display result inline in the notebook
app.run_server(mode='inline')

One approach could be to put your my-checklist options inside a variable and pass this variable to the options property of my-checklist:
all_options=[
{"label": "New York City", "value": "NYC"},
{"label": "Montréal", "value": "MTL"},
{"label": "San Francisco", "value": "SF"},
]
Then you can check whether the number of selected options from my-checklist is equal to the length of all_options in your callback to determine if all options are selected.
Aditionally you need to check each time an option of my-checklist is selected in order to toggle the Select All checkbox.
For example:
#app.callback(
Output("my-checklist", "value"),
Output("all-or-none", "value"),
Input("all-or-none", "value"),
Input("my-checklist", "value"),
prevent_initial_call=True,
)
def select_all_none(all_selected, options):
ctx = dash.callback_context
triggerer_id = ctx.triggered[0]["prop_id"].split(".")[0]
my_checklist_options = []
all_or_none_options = []
if triggerer_id == "all-or-none":
if all_selected:
all_or_none_options = ["All"]
my_checklist_options = [option["value"] for option in all_options]
else:
if len(options) == len(all_options):
all_or_none_options = ["All"]
my_checklist_options = options
return my_checklist_options, all_or_none_options
I've dash.callback_context here to determine which Input triggered the callback. For more info on dash.callback_context see the documentation here.

Related

callback functions based on modal popup data not working (dash)

I am new to dash and am having trouble with writing a more complex callback function. The steps to my app are:
press a button to open a modal popup.
select options from a drop-down on the popup, which changes input options.
choose the desired input options
click a "submit" button to print (ultimately write) the input data.
I suspect I need either pattern matching callbacks, or chained callbacks because the errors I get say:
"Attempting to connect a callback Input item to component:
"id"
but no components with that id exist in the layout."
This is because the inputs don't appear until the modal popup and drop-down are activated.
Below is a minimal example with all the important layout features and should run on any machine. I specifically need help getting the last callback in the proper format to print the selected data from the modal drop-down.
Thanks!
import time
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from dash_bootstrap_templates import load_figure_template
################################################################################################
app = dash.Dash(external_stylesheets=[dbc.themes.CERULEAN])
report_list = [
{"label": "drop down 1", "value": 1},
{"label": "drop down 2", "value": 2},
]
body1 = html.Div([
html.H6(
"Enter value (required)"
),
dcc.Input(
id = 'report-1',
type = 'text',
placeholder = "value",
debounce=True,
required=True,
),
html.Div(html.Br(),),
html.H6(
"Choose a new reach type (required)"
),
dcc.RadioItems(
id = 'type_radio',
options=[
{'label':'radio1','value':1},
{'label':'radio2', 'value':2},],
className='btn-group-vertical p-2'),
])
body2 = html.Div([
html.H6(
"Enter value (required)",
),
dcc.Input(
id = 'report-2',
type = 'text',
placeholder = "value",
debounce=True,
required=True,
),
html.Div(html.Br(),),
html.H6(
"Input 1 (required)",
),
dcc.Input(
id = 'input1',
type = 'text',
placeholder = "input 1",
debounce=True,
required=True,
),
html.Div(html.Br(),),
html.H6(
"Input 2 (required)"),
dcc.Input(
id = 'input2',
type = 'text',
placeholder = "input 2",
debounce=True,
required=True,
),
])
################################################################################################
report_overlay = dbc.Modal(
[
dbc.ModalBody(
html.Div(children=[
html.Div([
'Description...'],
id="report-md"),
html.Div([
html.H5([
'Choose an option:'
]),
]),
html.Div([
dcc.Dropdown(
id='Report_DropBox',
options=report_list,
style={
# "textAlign":"center",
"width":"60%",
}
),
]),
html.Div([html.Br()]),
html.Div(id='report-options'), #different options for reporting a reach.
html.Div([html.Br()]),
html.Div([
dbc.Button(
"Submit",
id="report-submit",
outline=False,
color="secondary",
size="sm",
style={
"textTransform": "none",
"width":"30%"
},
),
]),
],
),
),
html.Div([html.Br()]),
html.Div(
id='submit_status',
style={"textAlign":"center", "width":"50%"}), #print status of submission.
html.Div([html.Br()]),
dbc.ModalFooter(
dbc.Button(
"Close",
id="report-close",
className="howto-bn"
)),
],
id="report-modal",
size="lg",
)
################################################################################################
app.layout = html.Div([
html.Br(),
dbc.Button(
"Report Reach",
id="report-open",
outline=False,
color="red",
style={
# "textTransform": "none",
"margin-right": "5px",
"color":"white",
"background-color":"#C42828",
"textAlign":"center",
},
),
report_overlay,
],style={"textAlign":"center"},
)
################################################################################################
##### callbacks
# Callback for modal popup
#app.callback(
Output("report-modal", "is_open"),
[Input("report-open", "n_clicks"), Input("report-close", "n_clicks")],
[State("report-modal", "is_open")],
)
def toggle_modal(n3, n4, is_open):
if n3 or n4:
return not is_open
return is_open
# Callback for different layouts based on drop down.
#app.callback(Output('report-options', 'children'),
Input('Report_DropBox', 'value'))
def render_content(report):
if report == 1:
return body1
if report == 2:
return body2
#attempted callback to print data based on modal input.
#app.callback(
Output("submit_status", "children"),
[
Input("Report_DropBox", "value"),
Input("report-1", "value"),
Input("report-2", "value"),
Input("type_radio", "value"),
Input("input1", "value"),
Input("input2", "value"),
Input("report-submit","n_clicks")
],
)
def print_report(dropbox, r1, r2, type, ip1, ip2, submit):
if submit:
if dropbox == 1:
r = r1
data = type
date_stamp = time.strftime("%d-%b-%Y %H:%M:%S", time.gmtime())
List = [r,data,date_stamp]
statement = html.Div([List])
elif dropbox == 2:
r = r2
data1 = ip1
data2 = ip2
date_stamp = time.strftime("%d-%b-%Y %H:%M:%S", time.gmtime())
List = [r,data1,data2,date_stamp]
statement = html.Div([List])
return statement
if __name__ == '__main__':
app.run_server(debug=True)

unable to add google form in plotly

Below is my code, but the code not works,
first 5 options in dropdown returns a graph and
option 6 needs to display a google form
without the 6th option the code is working fine, but the 6th option for displaying gform is throwing errror in dash
help me solve this
app.layout=html.Div(children=[dcc.Dropdown(
id='FirstDropdown',
options=[
{'label':"graph1",'value':'v1'},
{'label':"graph2",'value':'v2'},
{'label':"graph3,'value':'v3'},
{'label':"graph4",'value':'v4'},
{'label':"graph 5",'value':'v5'},
{'label':"g-form",'value':'v6'}
],
placeholder="Please choose an option",
value='v1'
),
html.Div(dcc.Graph(id='graph'))
])
#app.callback(
[Output('graph','figure')],
[Input(component_id='FirstDropdown',component_property='value')]
)
def select_graph(value):
if value=='v1':
return fig11
elif value=='v2':
return fig21
elif value=='v3':
return fig31
elif value=='v4':
return fig411
elif value=='v5':
return fig_all
elif value == 'v6':
google_form_iframe = html.Iframe(
width='640px',
height='947px',
src="https://docs.google.com/forms/d/e/1FAIpQLSfkIgHkKlD5Jl4ewfWpA8y9D65UbhdrvZ0k7qXOBI7uFN1aNA/vi ewform?embedded=true"
)
return google_form_iframe
fundamentally dcc.Figure() and html.IFrame() are separate dash components. Hence if you what to display a figure of Iframe based on dropdown use a div container. From callback return child component that fits into this container
to make full working example, have used COVID vaccination data to generate 5 figures that can be selected from drop down.
if google form is selected then return that
import pandas as pd
import plotly.express as px
from jupyter_dash import JupyterDash
import dash
from dash import dcc, html
from dash.dependencies import Input, Output, State
import json
df = pd.read_csv(
"https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations.csv"
)
df["date"] = pd.to_datetime(df["date"])
df = df.sort_values(["date", "iso_code"])
figs = {
f"v{n+1}": px.bar(
df.loc[(df["date"].dt.day_of_week == 6) & df["iso_code"].isin(["DEU", "FRA"])],
x="date",
y=c,
color="iso_code",
)
for n, c in zip(range(5), df.select_dtypes("number").columns)
}
# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dcc.Dropdown(
id="FirstDropdown",
options=[
{"label": "graph1", "value": "v1"},
{"label": "graph2", "value": "v2"},
{"label": "graph3", "value": "v3"},
{"label": "graph4", "value": "v4"},
{"label": "graph 5", "value": "v5"},
{"label": "g-form", "value": "v6"},
],
placeholder="Please choose an option",
value="v1",
),
dash.html.Div(
id="graph_container",
),
]
)
#app.callback(
Output("graph_container", "children"),
Input("FirstDropdown", "value"),
)
def select_graph(value):
if value in figs.keys():
return dash.dcc.Graph(figure=figs[value])
else:
return html.Iframe(
width="640px",
height="947px",
src="https://docs.google.com/forms/d/e/1FAIpQLSfkIgHkKlD5Jl4ewfWpA8y9D65UbhdrvZ0k7qXOBI7uFN1aNA/vi ewform?embedded=true",
)
app.run_server(mode="inline")

Cover Whole Screen with Plotly Chart on Dash App

Currently when I use Plotly with Dash there's a large blank space under the graph on the rest of the web app, however when I use fig.show() method the chart takes up the whole screen as intended.
The Two images below should provide all the information. I would like my dash app (bottom pic) to look taller as in the simple plotly version (top pic) picture.[]
import pandas as pd
import plotly.express as px # (version 4.7.0 or higher)
import plotly.graph_objects as go
from dash import Dash, dcc, html, Input, Output # pip install dash (version 2.0.0 or higher)
import dash_bootstrap_components as dbc
import yfinance as yf
from plotly.subplots import make_subplots
app = Dash(__name__, external_stylesheets=[dbc.themes.LUX])
# ------------------------------------------------------------------------------
# App layout
app.layout = html.Div(style={
'height':'100vh',
'padding': 10
}, children=[
# html.H1("MarketFeel", style={'text-align': 'center'}),
# html.H3("Unlock the Sentiment of the Markets", style={'text-align': 'center'}),
dcc.Dropdown(id="slct_Market",
options=[
{"label": "Bitcoin", "value": "BTCSentiment.csv"},
{"label": "Ethereum", "value": "ETHSentiment.csv"},
{"label": "Dogecoin", "value": "DOGESentiment.csv"},
{"label": "Cardano", "value": "ADASentiment.csv"},
{"label": "Kucoin", "value": "KCSSentiment.csv"},
{"label": "Vechain", "value": "VETSentiment.csv"},
{"label": "AMC", "value": "AMCSentiment.csv"},
{"label": "Amazon", "value": "AMZNSentiment.csv"},
{"label": "Dash", "value": "DASHSentiment.csv"},
{"label": "Facebook", "value": "FBSentiment.csv"},
{"label": "Litecoin", "value": "LTCSentiment.csv"},
{"label": "Tesla", "value": "TSLASentiment.csv"},
{"label": "Ripple", "value": "XRPSentiment.csv"},
],
multi=False,
value="BTCSentiment.csv",
style={'width': "40%"}
),
dcc.Dropdown(id="my-dpdn2",
multi=True,
options=[
{"label": "Fear", "value": "Fear"},
{"label": "Anger", "value": "Anger"},
{"label": "Anticipation", "value": "Anticipation"},
{"label": "Trust", "value": "Trust"},
{"label": "Surprise", "value": "Surprise"},
{"label": "Sadness", "value": "Sadness"},
{"label": "Disgust", "value": "Disgust"},
{"label": "Joy", "value": "Joy"}],
value=["Fear"],
),
html.Div(id='output_container', children=[]),
html.Br(),
dcc.Graph(id='my_sentiment_chart', figure={}, )
])
# ------------------------------------------------------------------------------
# Connect the Plotly graphs with Dash Components
#app.callback(
[Output(component_id='output_container', component_property='children'),
Output(component_id='my_sentiment_chart', component_property='figure')],
[Input(component_id='slct_Market', component_property='value'),
Input(component_id='my-dpdn2', component_property='value')]
)
# Section updates graph shown depending on what options user selects from above drop down menus
def update_graph(mkt_selected, option_slctd):
# print(option_slctd[0])
df = pd.read_csv(mkt_selected)
df.reset_index(inplace=True)
container = "The Emotion chosen by user was: {}".format(option_slctd)
container1 = ""
dff = df.copy()
# Plotly Express
myDict = {"BTCSentiment.csv": 'Bitcoin',
"DOGESentiment.csv": 'Dogecoin',
"ETHSentiment.csv": 'Ethereum',
"ADASentiment.csv": 'Cardano',
"KCSSentiment.csv": 'Kucoin',
"VETSentiment.csv": 'Vechain',
}
priceDict = {"BTCSentiment.csv": 'BTC-USD',
"DOGESentiment.csv": 'DOGE-USD',
"ETHSentiment.csv": 'ETH-USD',
"ADASentiment.csv": 'ADA-USD',
"KCSSentiment.csv": 'Kucoin',
"VETSentiment.csv": 'VET-USD',
"AMCSentiment.csv": 'AMC',
"DASHSentiment.csv": 'DASH-USD',
"FBSentiment.csv": 'FB',
"LTCSentiment.csv": 'LTC-USD',
"TSLASentiment.csv": 'TSLA',
"XRPSentiment.csv": 'XRP-USD'
}
startDate = dff['Date'][1]
endDate = dff['Date'].iloc[-1]
data = yf.download(priceDict[mkt_selected], start=startDate,
end=endDate).reset_index().pipe \
(lambda d: d.rename(columns={c: c.lower()
if c != "Date" else "datetime" for c in d.columns}))
fig = make_subplots(specs=[[{"secondary_y": True}]])
if len(option_slctd) != 0:
for item in option_slctd:
fig.add_trace(go.Line(name=item, x=dff['Date'], y=dff[item]),
secondary_y=True)
fig.add_trace(go.Candlestick(name="Price",
x=data['datetime'],
open=data['open'],
high=data['high'],
low=data['low'],
close=data['close'],
line=dict(width=1)),
secondary_y=False)
fig.update_yaxes(title_text="Emotion Level (%)", secondary_y=True)
else:
fig.add_trace(go.Candlestick(name="Price",
x=data['datetime'],
open=data['open'],
high=data['high'],
low=data['low'],
close=data['close'],
line=dict(width=1)),
secondary_y=False)
fig.update_yaxes(title_text="Price", secondary_y=False)
fig.update_yaxes(title_text="Price", secondary_y=False)
fig.update_traces(line_color="Blue", selector=dict(type='Line'))
fig.update_layout(
autosize=True,
)
fig.update_xaxes(rangeslider_visible=True)
config = dict({'scrollZoom': True})
return container1,fig

Dash : Dynamically update an element based on radio option selected

I have a radio element and a text box element in my dash application. I'd like to update the text the field based on the selected option from a callback.
dbc.InputGroup(
[
dbc.RadioItems(
id="type",
persistence=True,
persistence_type="memory",
options=[
{"label": "option1", "value": "option1"},
{"label": "option2", "value": "option2"}
],
value="option1",
style={"margin-left":"8px"}
),
],
style={"margin-top":"20px","width": "80%", "float": "left"},
),
dbc.InputGroup(
[
dbc.InputGroupAddon("Floor", style={"margin-left":"8px"}),
dbc.Input(
id="floor",
persistence=True,
persistence_type="memory"
),
],
),
How do I make the text "Floor" to be dynamic based on the option selected in the radio?
You need to use the #app.callback in order to make your InputGroupAddon dynamic
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = (
html.Div([
dbc.InputGroup([
dbc.RadioItems(
id="type",
persistence=True,
persistence_type="memory",
options=[
{"label": "option1", "value": "option1"},
{"label": "option2", "value": "option2"}
],
value="option1",
style={"margin-left":"8px"}
),
],
style={"margin-top":"20px","width": "80%", "float": "left"},
),
dbc.InputGroup([
dbc.InputGroupAddon(
id='dbc-input-addon',
style={"margin-left":"8px"}),
dbc.Input(
id="floor",
persistence=True,
persistence_type="memory"
),
])
])
)
#app.callback(
Output(component_id='dbc-input-addon', component_property='children'),
[Input(component_id='type', component_property='value')]
)
def change_input(option_value):
if option_value == 'option1':
input_txt = 'Floor'
elif option_value == 'option2':
input_txt = 'No floor'
return input_txt
if __name__ == '__main__':
app.run_server(debug=True)

How can user add their own values to a dash_core_components.Dropdown?

In my dropdown you should select from a list of workplaces but you should also be able to insert your own value.
How can I add a input field like "add value..." at the end of the list?
A basic version that implements Kay's suggestion of creating a callback that appends an option to the list of options. The following example uses a button click as Input and an input value as State:
from dash import Dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Output, Input, State
app = Dash(__name__)
app.layout = html.Div(
[
dcc.Dropdown(
id="dropdown",
options=[
{"label": "a", "value": "a"},
{"label": "b", "value": "b"},
{"label": "c", "value": "c"},
],
value="a",
),
dcc.Input(id="input", value="", placeholder="add value..."),
html.Button("Add Option", id="submit", n_clicks=0),
]
)
#app.callback(
Output("dropdown", "options"),
Input("submit", "n_clicks"),
State("input", "value"),
State("dropdown", "options"),
prevent_initial_call=True,
)
def add_dropdown_option(n_clicks, input_value, options):
return options + [{"label": input_value, "value": input_value}]
if __name__ == "__main__":
app.run_server()

Categories