Plotly Dash Update Drop Down from call back where data frame inside the call back
Question:
I am trying to update the drop-down menu from the data frame column value where my data frame is generated inside call back since I am taking user inputs and extracting some data from API.
I want to create a filter in the dropdown that’s why I want that drop-down updated dynamically using the data frame column.
so in a call back I have df[‘name_id’] through which I want to update the segment dropdown.
I have taken the only important line to break in my code since the code is too lengthy:
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import datetime
import dash_table
import httplib2
import pandas as pd
import requests
import io
import time
from Dash_App.app import app
from dash.dependencies import Input, Output, State
from oauth2client import GOOGLE_REVOKE_URI, GOOGLE_TOKEN_URI, client
from oauth2client import client, GOOGLE_TOKEN_URI
from datetime import date, timedelta
from apiclient import discovery
row1 = html.Div(
[
dbc.Row([
dbc.Col([
dbc.Input(id="client_id",
type="text",
placeholder="Client ID",
style={'width': '150px'}, persistence=True,
persistence_type='memory'),
]),
], align="center"),
], style={'margin-top': 20, 'margin-left': -90}
)
row2 = html.Div([
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='segment',
options=[{'label': i, 'value': i} for i in "what"],
multi=True,
style={'width': '250px'},
placeholder='Segment'),
]),
])
])
tab_2_layout = dbc.Container(children=[
row1,
html.Br(),
row2,
]
)
@app.callback(Output('output_div-ga', 'children'),
[Input('submit-button', 'n_clicks')],
[State('client_id', 'value'),
],
)
def ga_output(clicks, client_id):
if clicks is not None:
my_client_id = client_id
credentials = client.OAuth2Credentials(
access_token=None, # set access_token to None since we use a refresh token
client_id=my_client_id)
credentials.refresh(httplib2.Http()) # refresh the access token (optional)
http = credentials.authorize(httplib2.Http()) # apply the credentials
service_v3 = discovery.build('analytics', 'v3', http=http)
segments = service_v3.management().segments().list().execute()
df = pd.DataFrame(segments['items'])
df = df[['name', 'id']]
df['name_id'] = df.name.astype(str).str.cat(df.id.astype(str), sep=':')
return html.Div([dcc.Store('memory'),
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in dff.columns],
data=dff.to_dict("rows"), persistence=True, persistence_type='memory',
export_format="csv",
),
])
Answers:
I am able to solve this by generating form inside call back.
return html.Div([
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='segment',
options=[{'label': i, 'value': i} for i in df['name_id'].unique()],
persistence=True, persistence_type='memory',
multi=True,
style={'width': '250px', 'margin-left': -250, 'margin-top': 10},
placeholder='Segment'),
]), ]), ])
What worked for me was to give each column that you want to edit an id
, make it editable and then update the dropdown options in the DataTable
. I also returned the whole DataTable
in my callback.
app.callback(
Output("table-dropdown-container", "children"),
Input("input-data-table-id", "data"),
)(self.update_unlabelled_shops_table)
…
dt = (
dash_table.DataTable(
id='table-id',
data=df.to_dict("records"),
columns=[{"name": i, "id": i} if i != column_name else {"name": i, "id": i, "editable": True, "presentation": "dropdown"} for i in df.columns],
page_size=8,
dropdown={
column_name: {
"options": [
{"label": i, "value": i}
for i in df[column_name].unique()
]
},
},
),
)
return dt
except Exception as e:
print(e)
return [None]
And to create your div block.
def create_div(self):
return html.Div(
[
dash_table.DataTable(
id='table-id',
columns=[],
editable=True,
dropdown={},
),
html.Div(id="table-dropdown-container"),
]
)
Hope this helps somebody…
I am trying to update the drop-down menu from the data frame column value where my data frame is generated inside call back since I am taking user inputs and extracting some data from API.
I want to create a filter in the dropdown that’s why I want that drop-down updated dynamically using the data frame column.
so in a call back I have df[‘name_id’] through which I want to update the segment dropdown.
I have taken the only important line to break in my code since the code is too lengthy:
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import datetime
import dash_table
import httplib2
import pandas as pd
import requests
import io
import time
from Dash_App.app import app
from dash.dependencies import Input, Output, State
from oauth2client import GOOGLE_REVOKE_URI, GOOGLE_TOKEN_URI, client
from oauth2client import client, GOOGLE_TOKEN_URI
from datetime import date, timedelta
from apiclient import discovery
row1 = html.Div(
[
dbc.Row([
dbc.Col([
dbc.Input(id="client_id",
type="text",
placeholder="Client ID",
style={'width': '150px'}, persistence=True,
persistence_type='memory'),
]),
], align="center"),
], style={'margin-top': 20, 'margin-left': -90}
)
row2 = html.Div([
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='segment',
options=[{'label': i, 'value': i} for i in "what"],
multi=True,
style={'width': '250px'},
placeholder='Segment'),
]),
])
])
tab_2_layout = dbc.Container(children=[
row1,
html.Br(),
row2,
]
)
@app.callback(Output('output_div-ga', 'children'),
[Input('submit-button', 'n_clicks')],
[State('client_id', 'value'),
],
)
def ga_output(clicks, client_id):
if clicks is not None:
my_client_id = client_id
credentials = client.OAuth2Credentials(
access_token=None, # set access_token to None since we use a refresh token
client_id=my_client_id)
credentials.refresh(httplib2.Http()) # refresh the access token (optional)
http = credentials.authorize(httplib2.Http()) # apply the credentials
service_v3 = discovery.build('analytics', 'v3', http=http)
segments = service_v3.management().segments().list().execute()
df = pd.DataFrame(segments['items'])
df = df[['name', 'id']]
df['name_id'] = df.name.astype(str).str.cat(df.id.astype(str), sep=':')
return html.Div([dcc.Store('memory'),
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in dff.columns],
data=dff.to_dict("rows"), persistence=True, persistence_type='memory',
export_format="csv",
),
])
I am able to solve this by generating form inside call back.
return html.Div([
dbc.Row([
dbc.Col([
dcc.Dropdown(
id='segment',
options=[{'label': i, 'value': i} for i in df['name_id'].unique()],
persistence=True, persistence_type='memory',
multi=True,
style={'width': '250px', 'margin-left': -250, 'margin-top': 10},
placeholder='Segment'),
]), ]), ])
What worked for me was to give each column that you want to edit an id
, make it editable and then update the dropdown options in the DataTable
. I also returned the whole DataTable
in my callback.
app.callback(
Output("table-dropdown-container", "children"),
Input("input-data-table-id", "data"),
)(self.update_unlabelled_shops_table)
…
dt = (
dash_table.DataTable(
id='table-id',
data=df.to_dict("records"),
columns=[{"name": i, "id": i} if i != column_name else {"name": i, "id": i, "editable": True, "presentation": "dropdown"} for i in df.columns],
page_size=8,
dropdown={
column_name: {
"options": [
{"label": i, "value": i}
for i in df[column_name].unique()
]
},
},
),
)
return dt
except Exception as e:
print(e)
return [None]
And to create your div block.
def create_div(self):
return html.Div(
[
dash_table.DataTable(
id='table-id',
columns=[],
editable=True,
dropdown={},
),
html.Div(id="table-dropdown-container"),
]
)
Hope this helps somebody…