How to set validation in dash? - python

The following code has first two columns with getpass.getuser() values and rest columns are normal with editable cells
import pandas as pd
import dash
from dash import dash_table, html
from dash.dependencies import Input, Output, State
import getpass
df = pd.read_csv('df.csv')
current_user = getpass.getuser()
df = df[(df.iloc[:, 0] == current_user) | (df.iloc[:, 1] == current_user)]
app = dash.Dash(__name__)
app.layout = html.Div([
dash_table.DataTable(
id='datatable',
columns=[
{'name': df.columns[0], 'id': df.columns[0], 'editable': False},
{'name': df.columns[1], 'id': df.columns[1], 'editable': False},
*[{'name': i, 'id': i, 'editable': True} for i in df.columns[2:]]
],
data=df.to_dict('records'),
editable=True
),
html.Button('Save Changes', id='save-button'),
html.Div(id='output')
])
#app.callback(Output('datatable', 'data'),
Output('output', 'children'),
Input('save-button', 'n_clicks'),
State('datatable', 'data'))
def save_changes(n_clicks, data):
if n_clicks:
df_new = pd.DataFrame.from_dict(data)
df_new = df_new[(df_new.iloc[:, 0] == current_user) | (df_new.iloc[:, 1] == current_user)]
df_new.to_csv('df.csv', index=False)
df_check = pd.read_csv('df.csv')
if df_check.equals(df_new):
return df_new.to_dict('records'), 'Changes saved!'
else:
raise Exception('Error saving changes.')
return data, ''
if __name__ == '__main__':
app.run_server(debug=True)
how to put validation in such a way that -
if the current user has getpass.getuser() values in first column, they can only edit and save data table values in df.csv only if they put "Sz", "Tx", "Ux" as values
if the current user has getpass.getuser() values in second column, they can only edit and save data table values in df.csv only if they put "Qr", "Fd", "Wv" as values

Related

Dash Filtering For Numeric Columns

I would like to use the code below in order to allow user to filter columns. The problem i sthat I cannot filter the columns with numerical values. How can I solve this issue? I was thinking to find column type, but it was not in the code
from dash import Dash, dcc, html, Input, Output, dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
df['id'] = df['country']
df.set_index('id', inplace=True, drop=False)
app = Dash(__name__)
app.layout = html.Div([
dcc.RadioItems(
[{'label': 'Read filter_query', 'value': 'read'}, {'label': 'Write to filter_query', 'value': 'write'}],
'read',
id='filter-query-read-write',
),
html.Br(),
dcc.Input(id='filter-query-input', placeholder='Enter filter query'),
html.Div(id='filter-query-output'),
html.Hr(),
dash_table.DataTable(
id='datatable-advanced-filtering',
columns=[
{'name': i, 'id': i, 'deletable': True} for i in df.columns
# omit the id column
if i != 'id'
],
data=df.to_dict('records'),
editable=True,
page_action='native',
page_size=10,
filter_action="native"
),
html.Hr(),
html.Div(id='datatable-query-structure', style={'whitespace': 'pre'})
])
#app.callback(
Output('filter-query-input', 'style'),
Output('filter-query-output', 'style'),
Input('filter-query-read-write', 'value')
)
def query_input_output(val):
input_style = {'width': '100%'}
output_style = {}
if val == 'read':
input_style.update(display='none')
output_style.update(display='inline-block')
else:
input_style.update(display='inline-block')
output_style.update(display='none')
return input_style, output_style
#app.callback(
Output('datatable-advanced-filtering', 'filter_query'),
Input('filter-query-input', 'value')
)
def write_query(query):
if query is None:
return ''
return query
#app.callback(
Output('filter-query-output', 'children'),
Input('datatable-advanced-filtering', 'filter_query')
)
def read_query(query):
if query is None:
return "No filter query"
return dcc.Markdown('`filter_query = "{}"`'.format(query))
#app.callback(
Output('datatable-query-structure', 'children'),
Input('datatable-advanced-filtering', 'derived_filter_query_structure')
)
def display_query(query):
if query is None:
return ''
return html.Details([
html.Summary('Derived filter query structure'),
html.Div(dcc.Markdown('''```json
{}
```'''.format(json.dumps(query, indent=4))))
])
if __name__ == '__main__':
app.run_server(debug=True)
Is there any way to handle this issue? Alternatively, where is the column type included in this script? I took it from Dash website.
If you want to write your own filter, you should enclose the column name with {}. For example, in order to get the value 708573 from pop column, you should write it as:
{pop} = 708573
But if you write your filter under a specific column, in this case, you only need to write = 708573
Please look in the documentation to familiarize yourself more to the filtering syntax.

create dynamic columns with dash plotly based on user selection

My idea is that my dash_table.Datatable insert new columns based on what the user select in my dropdown.
I've experimented different approachs to receive back a dataframe, dict or list with my actual columns and be able to update my table but either of these worked. Below a reproduceble example:
import pandas as pd
import dash_mantine_components as dmc
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash import html
from dash import Dash, Input, Output, dash_table, State
from dash.exceptions import PreventUpdate
import plotly.express as px
import json
from dash_bootstrap_templates import load_figure_template
import datetime
import base64
dff = {'Nome':['Random1','Random2','Random3','Random4'],'tipo':['Random11','Random22','Random33','Random44'],'a': ['1','2','3','4',], 'b':['b1','b2','b3','b4'], 'c':['c1','c2','c3','c4'], 'd':['d1','d2','d3','d3'],'Indicator Name':['a','b','c','d']}
dff = pd.DataFrame(dff)
db_filtered = pd.DataFrame(dff)
app = Dash(__name__, external_stylesheets= [dbc.themes.DARKLY, dbc_css])
#---------------------------------------------------------------------------------------------------------------------------------------#
# 1. FUNCTIONS CONSTRUCTION
# 1.1 - table_creation
#---------------------------------------------------------------------------------------------------------------------------------------#
#------------------------------------------------------- 1.1 ---------------------------------------------------------------------------#
def table_creation(db_filtered):
db_as_list = db_filtered.columns.to_list()
#print(db_as_list)
dash_table.DataTable(
data = [{
}],
columns = [{"name": i,
"id": i
} for i in db_as_list], #<------------ setting columns of datatable
editable=False, #<------------ setting preferences if is or not editable
filter_action="native", #<------------ Filters in columns
sort_action="native", #<------------
sort_mode="multi", #<------------
column_selectable="single", #<------------ Selectable only one column
row_selectable=False, #<------------ dont let select just a row
selected_columns=[], #<------------ no column is selected previously
selected_rows=[], #<------------ no row is selected previously
page_action="native",
page_current= 0, #<------------ First page will be show
page_size= 25) #<------------ n of funds to be showed
#---------------------------------------------------------------------------------------------------------------------------------------#
#---------------------------------------------------------------------------------------------------------------------------------------#
app.layout = html.Div([
#------------------------------------------------------- ---------------------------------------------------------------------------#
dbc.Card(
dbc.CardBody([
# ------------------------------------------------------------------------------------------------------------------#
dbc.Row([
dbc.Col([
html.Div([
dbc.Button("b1", color="warning", id='todos_button', n_clicks_timestamp='0'),
dbc.Button("b2", color="light",id='multimercado_button', n_clicks_timestamp='0' ),
dcc.Dropdown(dff['Indicator Name'].unique(), id = 'dropdown'),
])
]),
]),
#---------------------------------------------------------------------------------------------------------------------------------#
dbc.Row([
dbc.Col([
html.Div([
dash_table.DataTable(table_creation(db_filtered), id = 'tabela-dash',#calling the function with dff, but only will be displayed if the user use the button
)], className="m-4 dbc")
])
])
])
)
])
#---------------------------------------------------------------------------------------------------------------------------------------#
#---------------------------------------------------------------------------------------------------------------------------------------#
#-------------------------------------------------------- 3.1 --------------------------------------------------------------------------#
#app.callback(Output('tabela-dash', 'data'),
Input('multimercado_button','n_clicks_timestamp'),
Input('todos_button','n_clicks_timestamp')
)
def display(multimercado_button, todos_button ):
if int(multimercado_button) > int(todos_button): #Multimercado button
value = 'Macro Alta Vol'
db_filtered = pd.DataFrame(dff[dff['tipo'] == value])
db_filtered = db_filtered.loc[:,['Nome','tipo']]
print(db_filtered)
db_filtered = db_filtered.to_dict('Records')
return db_filtered #<------------ Extracting data as dict, easy way to do
elif int(todos_button) > int(multimercado_button):
db_filtered = pd.DataFrame(dff)
db_filtered = db_filtered.loc[:,['Nome','tipo']]
print(db_filtered)
db_filtered = db_filtered.to_dict('Records')
return db_filtered#<------------ Extracting data as dict, easy way to do
else:
db_filtered = pd.DataFrame(dff)
db_filtered = db_filtered.loc[:,['Nome','tipo']]
db_filtered = db_filtered.to_dict('Records')
return db_filtered #<------------ Extracting data as dict, easy way to do
#-------------------------------------------------------- 3.2 --------------------------------------------------------------------------#
#app.callback(
Output('tabela-dash', 'columns'),
[Input('dropdown', 'value')],
[State('tabela-dash', 'columns')]
)
def update_table(value, columns):
if value is None:
print('test 1: Value is None')
else:
print('test 1: Value is not None')
raise PreventUpdate
if columns is None:
print('test 2: Columns is None')
else:
print('test 2: Columns in not None')
app.run_server(debug=True, use_reloader=False)
I dont know why, but this code should work like this.
import dash
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from dash_table import DataTable, FormatTemplate
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='dropdown',
options=[{
'label': 'label: ' + id,
'value': id
} for id in ['b', 'c', 'd', 'e', 'f']]
),
DataTable(
id='table',
columns=[{
'name': x,
'id': x,
'selectable': True
} for x in ['a']],
column_selectable="single",
data=[{
'a': 'a' + str(x),
'b': 'b' + str(x),
'c': 'c' + str(x),
'd': 'd' + str(x),
'e': 'e' + str(x),
'f': 'f' + str(x)
} for x in range(0,100)]
)
])
#app.callback(
Output('table', 'columns'),
[Input('dropdown', 'value')],
[State('table', 'columns')]
)
def update_columns(value, columns):
if value is None or columns is None:
raise PreventUpdate
inColumns = any(c.get('id') == value for c in columns)
if inColumns == True:
raise PreventUpdate
columns.append({
'label': 'label: ' + value,
'id': value
})
return columns
if __name__ == '__main__':
app.run_server(debug=False)
i can imagine that my problem is that the function dont bring back the columns.

Update dashtable columns name dynamically

I'm trying to make a dashtable and its columns will be change dynamically based on dropdowns value.
Below is my sample code:
import pandas as pd
import numpy as np
import plotly.express as px
import dash
from dash import html
from dash import dcc
from dash.dependencies import Input, Output,State
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from dash import dash_table
df1 = pd.DataFrame({
'Contract No': ['VN122001','VN122002','VN122003','VN122004','VN122005'],
'Amount': [22071,20775,20841,21891,22395]})
df1 = df1.set_index('Contract No')
df2 = pd.DataFrame({
'Contract No': ['VN122001','VN122002','VN122003','VN122004','VN122005'],
'Cusname': ['A','B','C','D','E'],
'Branch': ['HN','HCM','HP','BN','DN']})
df2 = df2.set_index('Contract No')
app = dash.Dash(__name__,external_stylesheets=[dbc.themes.LUX])
app.layout = html.Div([
dbc.Row([
dbc.Col([
dcc.Dropdown(id='columns_name',placeholder="Columns name", # Dropdown for heatmap color
options=list_column,
value='Cusname',
multi=False,
disabled=False,
clearable=True,
searchable=True)
],width={'size':4,'offset':0,'order':1},style={'padding-top' : 15}),
]),
dbc.Row([
html.Div(
id = 'tableDiv',
className = 'tableDiv'
)
])
])
#app.callback(Output('tableDiv', 'children'),
[Input('columns_name', 'value')])
def update_columns_name(columns):
col_name = df2[[columns]]
df3 = pd.merge(df1, col_name, left_index=True, right_index=True)
df3 = df3.reset_index()
mycolumns = [{'name': i, 'id': i} for i in df3.columns]
return html.Div([
dash_table.DataTable(
id='table',
columns=mycolumns,
data=df3.to_dict("rows")
)
])
if __name__ == "__main__":
app.run_server(debug=False,port=1222)
Actually it is working well but when I try to create Tabs and then return it to Tab, nothing show. Below is my code to create Tab.
app.layout = html.Div([dbc.Tabs(
[dbc.Tab(label="Dashboard", tab_id="dashboard"),
dbc.Tab(label="Table", tab_id="table"),
],
id="tabs",
active_tab="dashboard"),
html.Div(id="tab-content", className="p-4"),
])
#app.callback(
Output("tab-content", "children"),
[Input("tabs", "active_tab")])
def render_tab_content(active_tab):
if active_tab == "dashboard":
return html.Div([dbc.Row([html.H5('Graphs')])])
elif active_tab == "table":
return html.Div([
dbc.Row([
html.Div(id = 'tableDiv',
className = 'tableDiv')
])
])
#app.callback(Output('tableDiv', 'children'),
[Input('columns_name', 'value')])
def update_columns_name(columns):
col_name = df2[[columns]]
df3 = pd.merge(df1, col_name, left_index=True, right_index=True)
df3 = df3.reset_index()
mycolumns = [{'name': i, 'id': i} for i in df3.columns]
return html.Div([
dash_table.DataTable(
id='table',
columns=mycolumns,
data=df3.to_dict("rows"))
])
if __name__ == "__main__":
app.run_server(debug=False,port=1222)
What should I do to fix this issue. Thank you.
This is the error javascript throws back in the browser console:
Object { message: "ID not found in layout", html: "Attempting to connect a callback Output item to component:\n \"tableDiv\"\nbut no components with that id exist in the layout.\n\nIf you are assigning callbacks to components that are\ngenerated by other callbacks (and therefore not in the\ninitial layout), you can suppress this exception by setting\n```suppress_callback_exceptions=True```.\nThis ID was used in the callback(s) for Output(s):\n tableDiv.children" } dash_renderer.v2_1_0m1644023699.min.js:2:84904
Object { message: "ID not found in layout", html: "Attempting to connect a callback Input item to component:\n \"columns_name\"\nbut no components with that id exist in the layout.\n\nIf you are assigning callbacks to components that are\ngenerated by other callbacks (and therefore not in the\ninitial layout), you can suppress this exception by setting\n```suppress_callback_exceptions=True```.\nThis ID was used in the callback(s) for Output(s):\n tableDiv.children" }
As it suggests, you are referring to id components that are generated by another callback (namely, callback render_tab_content generates the tableDiv div and is being referred to by update_column_name). This is a problem, as your tableDiv won't be present when you select the dashboard table but the callback may still be invoked (at least initially which is why you are having an issue to begin with).
It's best to perhaps have the contents of update_column_name combined with render_table_content and generate the column stuff you need through the one callback. You don't really gain anything from splitting into 2 callbacks in this instance, and if you really want, you can abstract the contents of the other callback into a normal function and just call it in render_tab_content. Here is a suggested adaptation:
def update_columns_name(columns):
col_name = df2[[columns]]
df3 = pd.merge(df1, col_name, left_index=True, right_index=True)
df3 = df3.reset_index()
mycolumns = [{'name': i, 'id': i} for i in df3.columns]
return (
html.Div([
dbc.Row([
html.Div([
html.Div([
dash_table.DataTable(
id='table',
columns=mycolumns,
data=df3.to_dict("rows")
)
])
],
id='tableDiv',
className='tableDiv')
])
])
)
#app.callback(
Output("tab-content", "children"),
[Input("tabs", "active_tab")],
[State('columns_name', 'value')]
)
def render_tab_content(active_tab, columns):
print(active_tab, columns)
if active_tab == "dashboard":
return html.Div([dbc.Row([html.H5('Graphs')])])
elif active_tab == "table":
return update_columns_name(columns)

Create dcc.Dropdown values Dynamically with Python Function

I am creating a search application with Dash by Plotly. I have a main search function for that creates a dataframe for the whole application that is defined as:
def search(term):
with index.searcher() as searcher:
parser = QueryParser("content", index.schema)
myquery = parser.parse(term)
results = searcher.search(myquery, limit=None)
print("Documents Containing ", term, ": ", len(results), "\n")
df = pd.DataFrame([i['date'], i['site'], i['system'], i['ticket'], i.score, i['level'], i['first'], i['last'], i['department'], \
i['detect'], i['code'],i['content'], i['description'], i['owner'], i['ownerGroup'], i['docId']] for i in results)
df.columns=['Reported Date', 'Site', 'System','Ticket ID', 'Score', 'Level', 'First', 'Last', 'Department', \
'Detection', 'Code', 'Content', 'Description', 'Owner', 'Owner Group', 'Document ID']
return df
I want users to be able to filter down search results with filters built into dcc.Dropdown. A couple of them can be hard-coded like so:
dcc.Dropdown(
id='siteFilter',
options=[
{'label': 'ABC', 'value': 'ABC'},
{'label': 'DEF', 'value': 'DEF'},
{'label': 'HIJ', 'value': 'HIJ'},
{'label': 'LMO', 'value': 'LMO'}
],
value=['ABC', 'DEF', 'HIJ', 'LMO'],
multi=True
However, some of the fields I want to filter on contain many options for a search and cannot be hard-coded. I can get the options to work. However, my application will not apply the filter changing when a user changes values. So, I have in my app.layout:
html.Div(dbc.Row([dbc.Col([
html.Label(["System Filter",
dcc.Dropdown(
id='systemFilter',
options='options',
value='All',
multi=True,
)
])
], width = 5)
]))
In my callback, I have tried several different options/combos of Outputs and States to achieve this with no luck. Callback:
#app.callback(
[Output(component_id='outTable', component_property='data'),
Output(component_id='outTable', component_property='columns'),
Output(component_id='commonWords', component_property='children'),
Output(component_id='systemFilter', component_property='options'),
#Output(component_id='systemFilter', component_property='value')
],
[Input(component_id='button', component_property='n_clicks')],
[State('searchId', 'value'),
State('siteFilter', 'value'),
State('detectFilter', 'value'),
State('levelFilter', 'value'),
State('codeFilter', 'value'),
#State(component_id='systemFilter', component_property='value')
])
def tableCreate(n_clicks, searchId, siteFilter, detectFilter, levelFilter, codeFilter):
if n_clicks > 0:
searchFrame = search(searchId)
###################### System Filter #######################################
#print('HERE DLKFSJSLDFKJSLDKJFJLKFDSJLDSKF')
#print(searchFrame['System'].unique())
#global optionsArray
optionsArray = searchFrame['System'].unique()
optionsArray = optionsArray.tolist()
print('Test')
print(optionsArray)
print('Test')
system_filter_options = [{'label': i, 'value': i} for i in optionsArray]
systemFilter = optionsArray
searchFrame = searchFrame[searchFrame['System'].isin(systemFilter)]
# Bunch of other code
searchFrame = searchFrame.drop(columns=['ContentNoStop'])
columns = [{'name': col, 'id': col} for col in searchFrame.columns]
data = searchFrame.to_dict(orient='records')
return data, columns, wordComponent, system_filter_options #, systemFilter
else:
return dash.no_update, dash.no_update, dash.no_update, dash.no_update
Essentially, one of 2 things happens. 1) The values return blank because they are not defined or 2) the options continually override the updated value parameter which I know is caused by the line systemFilter = optionsArray but I cannot seem to figure out a work around for this.
Here is an example image. I would like the results to populate all, but when a user filters by system and only selects a few, all my graphs and tables should update. But everytime, it does not seem to catch that. What am I missing here? How can the dcc.Dropdown selections be applied as a filter dynamically? I cannot and do not want to hard-code all the options
Easier reproduceable example:
I would like the dropdowns options to filter the table. If dog is selected, the table only shows dog.
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
import pandas as pd
from dash.dependencies import Input, Output, State
external_stylesheets = [dbc.themes.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
def createTable():
df = pd.DataFrame({'num_legs': [2, 4, 8, 0],
'num_wings': [2, 0, 0, 0],
'system': ['falcon', 'dog', 'spider', 'fish']},
index=[1, 2, 3, 4])
return df
app.layout = html.Div([
html.Button('Submit and Refresh', id='button', n_clicks=0, className='btn btn-primary'),
dbc.Row([dbc.Col([
html.Label(["System Filter",
dcc.Dropdown(
id='systemFilter',
options='options',
value='All',
multi=True,
)
])
], width = 5)
]),
html.Div([dash_table.DataTable(style_cell={
'whiteSpace': 'normal',
'height': 'auto',
'textAlign': 'left'
},
fill_width=False,
id='outTable',
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_deletable=True,
)
],
) ])
#app.callback(
[Output(component_id='outTable', component_property='data'),
Output(component_id='outTable', component_property='columns'),
Output(component_id='systemFilter', component_property='options'),
#Output(component_id='systemFilter', component_property='value')
],
[Input(component_id='button', component_property='n_clicks')],
[
State(component_id='systemFilter', component_property='value')
])
def tableCreate(n_clicks, systemFilter):
if n_clicks > 0:
searchFrame = createTable()
optionsArray = searchFrame['system'].unique()
optionsArray = optionsArray.tolist()
print('Test')
print(optionsArray)
print('Test')
system_filter_options = [{'label': i, 'value': i} for i in optionsArray]
systemFilter = optionsArray
searchFrame = searchFrame[searchFrame['system'].isin(systemFilter)]
columns = [{'name': col, 'id': col} for col in searchFrame.columns]
data = searchFrame.to_dict(orient='records')
return data, columns, system_filter_options#, systemFilter
if __name__ == '__main__':
app.run_server(debug=False)

keyerror 'column name' updating plotly dash figure

Issue:
I'm trying to load a simple plotly scatter plot, where
x axis = keyword
y axis = date
color = locale
however, even plotly throws a key error every time I add the "color" variable. The error code I get states that I don't have a column by that name, but when I print the column names I see the column there.
Anyone faced a similar issue?
Data:
Code:
# Importing needed libraries
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
import random
import datetime
import plotly.graph_objects as go
# Reading the dataframe
df = pd.read_csv('./beanstalk_app/ti_data_ti_dash_v1.csv')
categories = df['category']
locales = df['locale']
# clean dataframe
ti_data = df.copy()
ti_data = ti_data.sample(1000)
# Contents of the app
# 1.Controls
# 1.1 Dropdown list
locs = dcc.Dropdown(id='choose_loc',
options=[
{
'label': locale, 'value': locale
} for locale in locales.unique()
],
placeholder='Select Locale')
cats = dcc.Dropdown(id='choose_cat',
options=[
{
'label': c, 'value': c
} for c in categories.unique()
],
placeholder='Select Category')
# 1.2 DatePicker
datepick = dcc.DatePickerRange(
id='choose_date',
min_date_allowed=df.date.min(),
max_date_allowed=df.date.max(),
initial_visible_month=df.date.min(),
clearable=True,
start_date=df.date.min(),
end_date=df.date.max()
)
# 2.Interactive table
table = dash_table.DataTable(
id='datatable',
columns=[
{"name": i, "id": i, "selectable": True, "presentation": "markdown"}
if i == "google_query"
else {"name": i, "id": i, "selectable": True}
for i in df.columns
],
data=df.to_dict('records'),
editable=False,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
page_current=0,
page_size=10,
style_cell={
'whiteSpace': 'normal',
'height': 'auto',
},
)
# Initialize the app
app = dash.Dash(__name__)
app.title = 'Dot Graph Demo - All Entities'
app.layout = html.Div([
# modifiable table
dbc.Container([
dbc.Row(
[
dbc.Col(locs, width=4),
dbc.Col(cats, width=4),
dbc.Col(datepick, width=4)
]
),
dbc.Row(
table
),
], style={'backgroundColor': '#faf9f9'}),
# graphs resulting from modified table
html.Div(dcc.Graph(id='key_graph_l'))
],
style={'backgroundColor': '#faf9f9'})
# add callback functions
#app.callback(
Output('datatable', 'data'),
[
Input('choose_cat', 'value'),
Input('choose_loc', 'value'),
Input('choose_date', 'start_date'),
Input('choose_date', 'end_date')
]
)
def update_table(choose_cat, choose_loc, start_date, end_date):
df = ti_data.copy()
df['date'] = pd.to_datetime(df['date'])
df['date'] = df['date'].dt.date
if choose_cat is not None:
df = df[df['category'] == choose_cat]
if choose_loc is not None:
df = df[df['locale'] == choose_loc]
if start_date is not None and end_date is not None:
start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d").date()
end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d").date()
df = df.loc[(df.date >= start_date) & (df.date <= end_date)]
data = df.to_dict('records')
return data
#app.callback(
Output('datatable', 'style_data_conditional'),
Input('datatable', 'selected_columns')
)
def update_styles(selected_columns):
return [{
'if': {'column_id': column},
'background_color': '#D2F3FF'
} for column in selected_columns]
#app.callback(
Output('key_graph_l', 'figure'),
[
Input('choose_date', 'start_date'),
Input('choose_date', 'end_date'),
Input('choose_cat', 'value'),
Input('choose_loc', 'value')
]
)
def update_key_l(choose_loc, choose_cat, start_date, end_date):
df = ti_data.copy()
if choose_cat is not None:
df = df[df['category'] == choose_cat]
if choose_loc is not None:
df = df[df['locale'] == choose_loc]
if start_date is not None and end_date is not None:
df = df.loc[(df.date >= start_date) & (df.date <= end_date)]
df = df.sort_values('total_count', ascending=False)[:25]
figure = px.scatter(df, x='keyword', y='date', color='locale', size='total_count',labels={'keyword': 'Keyword', 'total_count': 'Total Count', 'locale': 'Locale', 'date': 'Date'},
title='Weighing top words accross locales')
return figure
# requirements for beanstalk (aws)
if __name__ == '__main__':
app.run_server(debug=True)
The reason for the error is that the order of the arguments in the callback function is different. The error occurs because the date format that is set when there is no calendar selection does not match the date format handled in Dash.
# Importing needed libraries
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
import random
import datetime
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
# Reading the dataframe
df = pd.read_csv('./beanstalk_app/ti_data_ti_dash_v1.csv')
categories = df['category']
locales = df['locale']
# clean dataframe
ti_data = df.copy()
ti_data = ti_data.sample(4) # sample data
# Contents of the app
# 1.Controls
# 1.1 Dropdown list
locs = dcc.Dropdown(id='choose_loc',
options=[
{
'label': locale, 'value': locale
} for locale in locales.unique()
],
placeholder='Select Locale')
cats = dcc.Dropdown(id='choose_cat',
options=[
{
'label': c, 'value': c
} for c in categories.unique()
],
placeholder='Select Category')
# 1.2 DatePicker
datepick = dcc.DatePickerRange(
id='choose_date',
min_date_allowed=df.date.min(),
max_date_allowed=df.date.max(),
initial_visible_month=df.date.min(),
clearable=True,
start_date=df.date.min(),
end_date=df.date.max()
)
# 2.Interactive table
table = dash_table.DataTable(
id='datatable',
columns=[
{"name": i, "id": i, "selectable": True, "presentation": "markdown"}
if i == "google_query"
else {"name": i, "id": i, "selectable": True}
for i in df.columns
],
data=df.to_dict('records'),
editable=False,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
page_current=0,
page_size=10,
style_cell={
'whiteSpace': 'normal',
'height': 'auto',
},
)
# Initialize the app
app = dash.Dash(__name__)
app.title = 'Dot Graph Demo - All Entities'
app.layout = html.Div([
# modifiable table
dbc.Container([
dbc.Row(
[
dbc.Col(locs, width=4),
dbc.Col(cats, width=4),
dbc.Col(datepick, width=4)
]
),
dbc.Row(
table
),
], style={'backgroundColor': '#faf9f9'}),
# graphs resulting from modified table
html.Div(dcc.Graph(id='key_graph_l'))
],
style={'backgroundColor': '#faf9f9'})
# add callback functions
#app.callback(
Output('datatable', 'data'),
[
Input('choose_cat', 'value'),
Input('choose_loc', 'value'),
Input('choose_date', 'start_date'),
Input('choose_date', 'end_date')
]
)
def update_table(choose_cat, choose_loc, start_date, end_date):
df = ti_data.copy()
# df['date'] = pd.to_datetime(df['date'])
# df['date'] = df['date'].dt.date
if choose_cat is not None:
df = df[df['category'] == choose_cat]
if choose_loc is not None:
df = df[df['locale'] == choose_loc]
if start_date is not None and end_date is not None:
# start_date = datetime.datetime.strptime(start_date, "%Y-%m-%dT00:00:00").date()
# end_date = datetime.datetime.strptime(end_date, "%Y-%m-%dT00:00:00").date()
df = df.loc[(df.date >= start_date) & (df.date <= end_date)]
data = df.to_dict('records')
return data
#app.callback(
Output('datatable', 'style_data_conditional'),
Input('datatable', 'selected_columns')
)
def update_styles(selected_columns):
return [{
'if': {'column_id': column},
'background_color': '#D2F3FF'
} for column in selected_columns]
#app.callback(
Output('key_graph_l', 'figure'),
[
Input('choose_cat', 'value'),
Input('choose_loc', 'value'),
Input('choose_date', 'start_date'),
Input('choose_date', 'end_date')
]
)
def update_key_l(choose_cat, choose_loc, start_date, end_date):
df = ti_data.copy()
if choose_cat is not None:
df = df[df['category'] == choose_cat]
if choose_loc is not None:
df = df[df['locale'] == choose_loc]
if start_date is not None and end_date is not None:
df = df.loc[(df.date >= start_date) & (df.date <= end_date)]
df = df.sort_values('total_count', ascending=False)[:25]
figure = px.scatter(df, x='keyword', y='date', color='locale', size='total_count',labels={'keyword': 'Keyword', 'total_count': 'Total Count', 'locale': 'Locale', 'date': 'Date'},
title='Weighing top words accross locales')
return figure
# requirements for beanstalk (aws)
if __name__ == '__main__':
app.run_server(debug=True)

Categories

Resources