How to use multiple States in Dash callback? - python

I want to use multiple states in one callback. I didnt get it to work so I checked the below example from the documentation in which multiple states are used in a callback. Yet, when I run this code I get the error:
The input argument submit-button-state.n_clicks must be a list or tuple of
dash.dependencies.Inputs
Two questions:
Did something change and is the documentation outdated? (which seems unlikely as they have excellent documentation)
How do I get this to work?
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Input(id='input-1-state', type='text', value='Montréal'),
dcc.Input(id='input-2-state', type='text', value='Canada'),
html.Button(id='submit-button-state', n_clicks=0, children='Submit'),
html.Div(id='output-state')
])
#app.callback(Output('output-state', 'children'),
Input('submit-button-state', 'n_clicks'),
State('input-1-state', 'value'),
State('input-2-state', 'value'))
def update_output(n_clicks, input1, input2):
return u'''
The Button has been pressed {} times,
Input 1 is "{}",
and Input 2 is "{}"
'''.format(n_clicks, input1, input2)
if __name__ == '__main__':
app.run_server(debug=True)

The code in the question works – in recent versions of Dash, the current version being 1.20.0.
The requirement to have all Output, Input and State arguments of #app.callback in three seperate lists (as suggested in the answer by Ger) was removed in August 2020 in version 1.15.0 (see release notes). As seen by the examples in the documentation, doing so is not recommended anymore. If at all possible, update your Dash version instead of switching to the old style.

It is as straight forward as the error suggests. I already tried it some ties, but probably I made a typo somewhere.
The solution is to put the inputs, outputs and states all in a seperate list.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Input(id='input-1-state', type='text', value='Montréal'),
dcc.Input(id='input-2-state', type='text', value='Canada'),
html.Button(id='submit-button-state', n_clicks=0, children='Submit'),
html.Div(id='output-state')
])
#app.callback([Output('output-state', 'children')],
[Input('submit-button-state', 'n_clicks')],
[State('input-1-state', 'value'),
State('input-2-state', 'value')])
def update_output(n_clicks, input1, input2):
return u'''
The Button has been pressed {} times,
Input 1 is "{}",
and Input 2 is "{}"
'''.format(n_clicks, input1, input2)
if __name__ == '__main__':
app.run_server(debug=True)

Related

Dash error : 'dash_core_components' has no attribute 'send dataframe'

In my dash I have a callback that create a pd.to_dict object that is stored with dcc.Store, in order to be used for further plots.
I am trying to create a download button to download this created data frame.
This is part of my code (removed other import or layout options) :
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
app = dash.Dash(__name__)
app.layout = html.Div([
html.H2('Enter a text query'),
dcc.Store(id='memory'),
html.Button('Submit', id='button', n_clicks=0),
html.Button("Download CSV", id="csv"),
dcc.Download(id="download-df")])
#app.callback(
Output('memory', 'data'),
[Input('button', 'n_clicks')],
[State('searchterm', 'value')]
)
def create_df_func(n_clicks, searchterm):
#some code to create df
return df.to_dict(orient='records')
#app.callback(
Output('download-df', 'data'),
[Input('csv', 'n_clicks')],
[State('memory', 'data')],
prevent_initial_call=True,
)
def download_csv(n_clicks, df):
data = pd.DataFrame(df)
return dcc.send_data_frame(data.to_csv, "mydf.csv")
if __name__ == '__main__':
app.run_server(debug=True)
But when running the app.py, I get 'dash_core_components' has no attribute 'send dataframe', even though it has it.
I have dash version 2.0.0.
I have dash version 2.0.0
Replace how you import dash core components from this
import dash_core_components as dcc
to this
from dash import dcc
As of Dash 2, the development of dash-core-components has been moved to the main Dash repo
quote source

Python plotly dash - button to link to webpage

I am using python dash and I'd like to have a button below my table that when clicked, will take the user to a specific webpage. I am very - VERY - new to using dash so I'm not even sure if this functionality exists. I did search this topic specifically to python dash and came up empty handed. Any and all help is appreciated, thank you!
You can use dash_bootstrap_components or dbc to do that. Check this page for more detailed information about dbc: https://dash-bootstrap-components.opensource.faculty.ai/docs/components/button/
To summarize, what you need to do:
If you haven't done yet, pip install dbc:
pip install dash-bootstrap-components
Import it to your code:
import dash_bootstrap_components as dbc
Configure your app with one of the dbc themes. When you creat the app, just include an external_stylesheet:
app = Dash(external_stylesheets=[dbc.themes.CYBORG])
Include the dbc.Button componen in your app (see examples in documentation or below).
Here is an example:
from dash import Dash, html
import dash_bootstrap_components as dbc
app = Dash(external_stylesheets=[dbc.themes.CYBORG])
app.layout = html.Div([
html.Div("Default format"),
dbc.Button(
children='Open Page',
id='button_plain',
href = "https://stackoverflow.com/"),
html.Br(),
html.Br(),
html.Br(),
html.Div("Modify format"),
dbc.Button(
children='Open Page',
id='button_format',
color = "primary",
outline = True, #more lightweight format
size = "lg", #sm, lg
href = "https://stackoverflow.com/"),
])
if __name__ == '__main__':
app.run_server(debug=True)
More about dbc Themes: https://bootswatch.com/
use this for button example and to learn more please use this
link:https://dash.plotly.com/dash-core-components.
import dash
import dash_html_components as html
import dash_core_components as dcc
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div(dcc.Input(id='input-box', type='text')),
html.Button('Submit', id='button'),
html.Div(id='output-container-button',
children='Enter a value and press submit')
])
#app.callback(
dash.dependencies.Output('output-container-button', 'children'),
[dash.dependencies.Input('button', 'n_clicks')],
[dash.dependencies.State('input-box', 'value')])
def update_output(n_clicks, value):
return 'The input value was "{}" and the button has been clicked {} times'.format(
value,
n_clicks
)
if __name__ == '__main__':
app.run_server(debug=True)

Python Plotly Dash - How do I access updated component value without using callback?

When you enter something other than "test" in the input box, and press enter, the label should change to reflect that input.
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
markerNameInp = dbc.Input(id='markerNameInp',placeholder='Enter name..',
style={'min-width':'150px','width':'15%',
'margin-right':'20px','display':'inline-block',
'margin-bottom':'10px'}, value = 'test')
app = dash.Dash()
app.layout = html.Div(style={'font':'Frutiger Linotype, sans-serif',
'margin-left':'50px','margin-right':'50px'},
children=[
html.Div([markerNameInp]),
dbc.Button('Enter',id='enter',
color = 'primary',
className='mr-1',
style={'height':'40px'}),
html.Div(id="output")
])
#app.callback(
Output(component_id='output', component_property='children'),
[Input(component_id='enter', component_property='n_clicks')]
)
def func(enter_clicks):
return dbc.Label(markerNameInp.value)
if __name__ == "__main__":
app.run_server(debug=True)
Thanks in advance.
It is not possible to access an updated component value by accessing the Python object defined in the layout (markerNameInp.value). This is because each user accessing the Dash app will interact with it differently, and the state is stored on the client-side (the user's browser) rather than server-side (where the app is running, and where the Python object markerNameInp is located).
In your use case, it is possible to access the value property of markerNameInp by using dash.dependencies.State, which does not trigger the callback when the component is updated, but the value can still be captured.
Here's the updated code:
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
markerNameInp = dbc.Input(
id="markerNameInp",
placeholder="Enter name..",
style={
"min-width": "150px",
"width": "15%",
"margin-right": "20px",
"display": "inline-block",
"margin-bottom": "10px",
},
value="test",
)
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container(
children=[
html.Div([markerNameInp]),
dbc.Button("Enter", id="enter", color="primary", className="mr-1"),
html.Div(id="output"),
],
)
#app.callback(
Output("output", "children"),
[Input("enter", "n_clicks")],
[State("markerNameInp", "value")]
)
def func(n_clicks, marker_value):
return dbc.Label(marker_value)
if __name__ == "__main__":
app.run_server(debug=True)
(the bootstrap code was changed in order to reflect best practice, and some styling was removed for simplicity).

Plotly Dash URL pathname callback not firing when loading page

I am trying to build a multi-page Dash app using the url callback. My app called dash_apps.py looks like this:
from flask import Flask
from flask import request
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
server = Flask(__name__)
app = dash.Dash(
__name__,
server = server,
serve_locally = False,
requests_pathname_prefix = "/plotary/dash/",
)
app.layout = html.Div([
html.Div([
html.A([
html.Div(id="logo")
],href='https://man-es.com'),
html.Div([
html.H1('Keine Auswertung ausgewählt. ')
],id="description"),
],
id="navbar")]
)
#app.callback(Output('description', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
return html.Div([
html.H1('Auswertung Nr {}'.format(pathname))
])
#server.route('/plotary/dash/<int:report_id>')
def create_report(report_id):
return app
if __name__ == '__main__':
app.run_server(debug=True)
and is called through a wsgi.py that looks like this:
from dash_apps import server
if __name__ == "__main__":
server.run()
The server I am using runs nginx and I use a web socket that starts wsgi.py with gunicorn as is explained in this post.
Now if I open for example http://<ip.to.server>/plotary/dash/18 it will just state Keine Auswertung ausgewählt. although I would expect it to show Auswertung Nr. 18.
What am I missing here?
Alternatively I could also get the report_id from Flask's route, however I do not know how to then pass this variable to app.layout.
You need to add a dcc.Location object to your layout, and its id should match the one you are using on the callback ("url" in the case of Input('url', 'pathname')).
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div([
html.A([
html.Div(id="logo")
],href='https://man-es.com'),
html.Div([
html.H1('Keine Auswertung ausgewählt. ')
],id="description"),
],
id="navbar")]
)

display datatable after filtering rows from dropdown list in dash

I'm new to Dash. I would like to make a app, where I can select values from dropdown filter, filter dataset and display the data table. I'm using dash_table.
My example app code is below. No datatable is shown. Does anyone know what I did wrong? How can I render dash table in dash app?
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_table as dt
from dash.dependencies import Input, Output
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
app = dash.Dash(__name__)
states = df.State.unique().tolist()
app.layout = html.Div(
children=[
dcc.Dropdown(
id='filter_dropdown',
options=[{'label':st, 'value':st} for st in states],
value = states[0]
),
dt.DataTable(id='table-container') ]
)
#app.callback(
Output('table-container', 'data'),
[Input('filter_dropdown', 'value') ] )
def display_table(state):
dff = df[df.State==state]
return dff
if __name__ == '__main__':
app.run_server(debug=True)
BTW, do anyone know where I can find collections of dash app gallery with code?
You have to set the columns of your data table and return your dataframe as a dict in a special form. So change these two lines in your code to make it work.
dt.DataTable(id='table-container', columns=[{'id': c, 'name': c} for c in df.columns.values])
return dff.to_dict('records')
BTW, do anyone know where I can find collections of dash app gallery with code?
Best place with lots of examples with code is the Dash User Guide. You can for instance find the data table there.

Categories