ERROR in app: Exception on /_dash-update-component [POST] - python

I am trying to build a webpage with dash plotly. I want it to be interactive so whenever I insert values and click on the button.
Therefore, I use request on the API to get the results.
However, for some reason in terminal I can only see :
"ERROR in app: Exception on /_dash-update-component [POST]"
before inserting the values then it starts giving me success code
"POST /_dash-update-component HTTP/1.1" 200
Can anyone tell me how to solve the initial error?
Here is my code:
import json
import base64
import datetime
import requests
import pathlib
import math
import pandas as pd
import flask
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import dash_bootstrap_components as dbc
import plotly.express as px
from dash.dependencies import Input, Output, State
from plotly import tools
def fig1(data):
colors = {
'background': '#000220',
'text': '#FFFFFF'
}
today=datetime.datetime.today().strftime("%Y -%m -%d")
df_nested=data
df = df_nested.loc[df_nested['timestamp']>=today].groupby(['contract_name','contract_ticker_symbol']).mean('close.quote').reset_index()
fig = px.pie(df, values='close.quote', names='contract_name',labels={ "contract_name":'Contract Name',
"close.quote": "USD Value"} , title='Asset Allocation', color_discrete_sequence=px.colors.sequential.Plasma)
fig.update_traces(textposition='inside')
# fig.update_layout(uniformtext_minsize=12, uniformtext_mode='hide')
fig.update_layout(plot_bgcolor=colors['background'], paper_bgcolor=colors['background'],font_color=colors['text']
)
return fig
def fig2(data):
colors = {
'background': '#000220',
'text': '#FFFFFF'
}
df_nested=data
fig2=px.line(df_nested, x="timestamp", y="close.quote", color="contract_name",line_group="contract_ticker_symbol",labels={
"contract_name":'Contract Name',
"timestamp": "Date",
"close.quote": "USD Value",
"contract_ticker_symbol": "Ticker"
}, title='Asset Value Over Time', hover_name="contract_ticker_symbol",)
fig2.update_layout(plot_bgcolor=colors['background'], paper_bgcolor=colors['background'],font_color=colors['text'])
return fig2
app = dash.Dash(
__name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}],
)
app.title = ""
server = app.server
PATH = pathlib.Path(__file__).parent
# API Requests for news div
news_requests = requests.get(
"https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=API_KEY"
)
# API Call to update news
def update_news():
json_data = news_requests.json()["articles"]
df = pd.DataFrame(json_data)
df = pd.DataFrame(df[["title", "url"]])
max_rows = 10
return html.Div(
children=[
html.P(className="p-news", children="Headlines"),
html.P(
className="p-news float-right",
children="Last update : "
+ datetime.datetime.now().strftime("%H:%M:%S"),
),
html.Table(
className="table-news",
children=[
html.Tr(
children=[
html.Td(
children=[
html.A(
className="td-link",
children=df.iloc[i]["title"],
href=df.iloc[i]["url"],
target="_blank",
)
]
)
]
)
for i in range(min(len(df), max_rows))
],
),
]
)
# Dash App Layout
app.layout = html.Div(
className="row",
children=[
# Interval component for live clock
dcc.Interval(id="interval", interval=1 * 1000, n_intervals=0),
# Interval component for ask bid updates
dcc.Interval(id="i_bis", interval=1 * 2000, n_intervals=0),
# Interval component for graph updates
dcc.Interval(id="i_tris", interval=1 * 5000, n_intervals=0),
# Interval component for graph updates
dcc.Interval(id="i_news", interval=1 * 60000, n_intervals=0),
# Left Panel Div
html.Div(
className="three columns div-left-panel",
children=[
# Div for Left Panel App Info
html.Div(
className="div-info",
children=[
html.Img(
className="logo", src=app.get_asset_url("covalent.png")
),
html.H6(className="title-header", children="Covalent Analytics"),
html.P(
"""
Covalent Analytics provide portfolio tracking services across chains
"""
),
],
),
# Div for News Headlines
html.Div(
className="div-news",
children=[html.Div(id="news", children=update_news())],
),
],
),
# Right Panel Div
html.Div(
className="nine columns div-right-panel",
children=[
# Panel for orders
html.Div(
id="bottom_panel",
className="row div-bottom-panel",
children=[
html.Div(
className="display-inlineblock",
children=[
dcc.Input(id="address", placeholder="Enter wallet address...", type="text"),
dcc.Dropdown(id='chain_id',placeholder="Select Chain", options = [
{"label": "Ethereum", "value": "1"},
{"label": "Matic", "value": "137"},
{"label": "Binance Smart Chain", "value": "56"},
{"label": "Avalanche", "value": "43114"},
{"label": "Fantom", "value": "250"}
],
value=[],
),
],
),
html.Div(
className="display-inlineblock float-right",
children=[
html.Button('Add Wallet', id='btn-1', n_clicks=0)
],
), html.Div(id='container')
],
),
],
),
],
)
#JSON NORMALIZE
def normalize(data):
df=data['items']
df=pd.json_normalize(df,record_path=['holdings'],meta=['contract_ticker_symbol','contract_name',"contract_address"])
df=df[['contract_ticker_symbol','contract_name',"contract_address",'timestamp','close.quote']]
return df
#SET TIME FORMAT
def set_time(data):
return pd.to_datetime(data['timestamp'])
#app.callback(Output('container', 'children'),
Input("chain_id", "value"),
Input("address", "value"),)
def display(value,address):
ctx = dash.callback_context
api_key= "####"
if not ctx.triggered:
pass
else:
response = requests.get(f"https://api.covalenthq.com/v1/{value}/address/{address}/portfolio_v2/?format=format%3Dcsv&key={api_key}")
data=normalize(response.json())
data['timestamp']=set_time(data)
return [
dcc.Graph(
id='graph1',
figure=fig1(data)
),
dcc.Graph(
id='graph2',
figure=fig2(data)
)
]
# Dynamic Callbacks
# Function to open or close STYLE or STUDIES menu
def generate_open_close_menu_callback():
def open_close_menu(n, className):
if n == 0:
return "not_visible"
if className == "visible":
return "not_visible"
else:
return "visible"
return open_close_menu
# Function for hidden div that stores the last clicked menu tab
# Also updates style and studies menu headers
def generate_active_menu_tab_callback():
def update_current_tab_name(n_style, n_studies):
if n_style >= n_studies:
return "Style", "span-menu selected", "span-menu"
return "Studies", "span-menu", "span-menu selected"
return update_current_tab_name
# Function show or hide studies menu for chart
def generate_studies_content_tab_callback():
def studies_tab(current_tab):
if current_tab == "Studies":
return {"display": "block", "textAlign": "left", "marginTop": "30"}
return {"display": "none"}
return studies_tab
# Function show or hide style menu for chart
def generate_style_content_tab_callback():
def style_tab(current_tab):
if current_tab == "Style":
return {"display": "block", "textAlign": "left", "marginTop": "30"}
return {"display": "none"}
return style_tab
# Callback to update news
#app.callback(Output("news", "children"), [Input("i_news", "n_intervals")])
def update_news_div(n):
return update_news()
if __name__ == "__main__":
app.run_server(debug=False)

Related

Is it possible to use zoom from one graph in a Dash app to select input for second graph

I have a dash app that plots a dataframe which has a date component, and an entry that is either true or false. There are two graphs in the dashboard, one with the data vs date, and one with a percentage of True/False like below:
I can zoom in on the date range and select a subset clicking with the mouse.
I would like to feed this range back into the second graph.
At the moment to produce the above dashboard the relevant part of the code looks like:
from re import template
import pandas as pd
import plotly.express as px
from dash import Dash, Input, Output, dcc, html
from flask import globals
def init_dashboard(server):
evicted_df = pd.read_csv("app/data/evicted_jobs_node.csv", sep="\t")
all_df = pd.read_csv("app/data/all_jobs_node.csv", sep="\t")
all_df["datetime"] = pd.to_datetime(all_df["datetime"])
all_df = all_df.set_index(["datetime"])
all_df["evicted"] = all_df["id_job"].isin(evicted_df["id_job"])
app = Dash(__name__, server=server, routes_pathname_prefix="/dash/")
app.layout = html.Div(
[
html.Div(
className="row",
children=[
html.Div(
className="six columns",
children=[dcc.Graph(id="graph-with-dropdown")],
style=dict(width="75%"),
),
html.Div(
className="six columns",
children=[dcc.Graph(id="graph-with-dropdown2")],
style=dict(width="25%"),
),
],
style=dict(display="flex"),
),
html.Div(
className="row",
children=[
html.Div(
className="six columns",
children=[
dcc.Dropdown(
id="partition-dropdown",
options=[
"Partition (default is all)",
*all_df["partition"].unique(),
],
value="Partition (default is all)",
clearable=False,
searchable=False,
)
],
style={
"width": "50%",
"justify-content": "center",
},
),
html.Div(
className="six columns",
children=[
dcc.Dropdown(
id="node-dropdown",
options=[
"Number of Nodes (default is all)",
*sorted(
[
int(nodes)
for nodes in all_df["nodes_alloc"].unique()
]
),
],
value="Number of Nodes (default is all)",
clearable=False,
searchable=False,
)
],
style=dict(width="50%"),
),
],
style=dict(display="flex"),
),
]
)
init_callbacks(app, df, all_df)
return app.server
def init_callbacks(app, df, all_df):
#app.callback(
Output("graph-with-dropdown2", "figure"),
[Input("node-dropdown", "value"), Input("partition-dropdown", "value")],
)
def update_evicted_fig(selected_nodes, selected_partition):
if selected_nodes != "Number of Nodes (default is all)":
filtered_df = all_df[all_df["nodes_alloc"] == selected_nodes]
else:
filtered_df = all_df
if selected_partition != "Partition (default is all)":
filtered_df = filtered_df[filtered_df["partition"] == selected_partition]
x = ["Not Evicted", "Evicted"]
df1 = filtered_df.groupby(["evicted"]).count().reset_index()
fig = px.bar(
df1,
y=[
100
* filtered_df[filtered_df["evicted"] == False].size
/ filtered_df.size,
100
* filtered_df[filtered_df["evicted"] == True].size
/ filtered_df.size,
],
x=x,
color="evicted",
color_discrete_map={True: "red", False: "green"},
labels={"x": "Job Status", "y": "% of Jobs"},
)
fig.update_layout(transition_duration=500)
return fig
#app.callback(
Output("graph-with-dropdown", "figure"),
[Input("node-dropdown", "value"), Input("partition-dropdown", "value")],
)
def update_evicted_fig(selected_nodes, selected_partition):
if selected_nodes != "Number of Nodes (default is all)":
filtered_df = all_df[all_df["nodes_alloc"] == selected_nodes]
else:
filtered_df = all_df
if selected_partition != "Partition (default is all)":
filtered_df = filtered_df[filtered_df["partition"] == selected_partition]
print(
filtered_df[filtered_df["evicted"] == True]
.groupby([pd.Grouper(freq="6H")])
.sum(numeric_only=True)["node_hours"]
)
fig = px.bar(
x=filtered_df[filtered_df["evicted"] == False]
.groupby([pd.Grouper(freq="6H")])
.sum(numeric_only=True)["node_hours"]
.index,
y=filtered_df[filtered_df["evicted"] == False]
.groupby([pd.Grouper(freq="6H")])
.sum(numeric_only=True)["node_hours"],
labels={
"x": "Date",
"y": "Node hours",
},
title="Job Status",
barmode="stack",
)
fig.add_bar(
name="Evicted",
x=filtered_df[filtered_df["evicted"] == True]
.groupby([pd.Grouper(freq="6H")])
.sum(numeric_only=True)["node_hours"]
.index,
y=filtered_df[filtered_df["evicted"] == True]
.groupby([pd.Grouper(freq="6H")])
.sum(numeric_only=True)["node_hours"],
)
fig.update_layout(transition_duration=500)
return fig
return app.server
Is what I am hoping to do possible, and if so is there some documentation or a worked example someone could highlight for me?
I don't have you df so maybe you can refer my code to revise yours:
import pandas as pd
import numpy as np
import plotly.express as px
import dash
import dash_html_components as html
from dash import dcc
from dash_extensions.enrich import Input, Output, State, ServersideOutput
import dash_bootstrap_components as dbc
from dash.exceptions import PreventUpdate
df_2 = df[(df['BAS_DT'] >= '2022-01-01')]
df5 = df_2.pivot_table(values='USD_XC_BL',
index=['BAS_DT'],
aggfunc=np.sum).reset_index()
fig_3 = px.bar(df5,
x='BAS_DT',
y='USD_XC_BL',
labels='BAS_DT',
hover_name='BAS_DT', color_discrete_sequence=px.colors.qualitative.Alphabet)
fig_3.update_layout(xaxis_title="", yaxis_title="", plot_bgcolor='rgba(0,0,0,0)', margin=dict(l=0, r=0, t=0, b=0))
fig_3.update_xaxes(showline=False, showgrid=False),
fig_3.update_yaxes(showline=False, showgrid=False, separatethousands=True, tickformat=',.0f')
app = dash.Dash(__name__)
app.layout = html.Div([
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
html.H5('Amount by Currency', style={"text-align": "center"}),
dcc.Loading(children=[dcc.Graph(id='histogram_map', figure=fig_3)], color='#119DFF',
type='dot')
], width={'size': 12, 'offset': 0, 'order': 2}, style={"text-align": "left"}),
]),
])
]),
], xs=6),
dbc.Col([
dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
html.H5('Overdue Status', style={"text-align": "center"}),
dcc.Loading(children=[dcc.Graph(id='overdue_map', figure={})], color='#119DFF', type='dot')
], width={'size': 12, 'offset': 0, 'order': 2}, style={"text-align": "left"}),
]),
])
]),
], xs=6),
], className='p-2 align-items-stretch')
])
#app.callback(
Output('overdue_map', 'figure'),
Input('histogram_map', 'clickData'))
def update_y_timeseries(clickData):
if clickData:
country_name = clickData['points'][0]['hovertext']
df_3 = df[df['BAS_DT'] == country_name]
df_4 = df_3.pivot_table(values='CLOC_CUR_XC_BL',
index=['APL_DTL_NAME'],
aggfunc=pd.Series.nunique).reset_index()
fig = px.bar(df_4,
x='APL_DTL_NAME',
y='CLOC_CUR_XC_BL'
, color_discrete_sequence=px.colors.qualitative.Alphabet)
fig.update_layout(xaxis_title="", yaxis_title="", plot_bgcolor='rgba(0,0,0,0)') # plot_bgcolor='rgba(0,0,0,0)'
fig.update_xaxes(showline=False, showgrid=False),
fig.update_yaxes(showline=False, showgrid=False, separatethousands=True)
fig.update_traces(width=0.3)
return fig
else:
raise PreventUpdate
if __name__ == "__main__":
app.run_server(debug=True)
I'm using clickData to return point as date, and then use this date to filter data and then make new bar graph.
Hope this help.

Data from Django-model not showing updates in Django dash app

import plotly.express as px
import pandas as pd
from django_plotly_dash import DjangoDash
from product.models import Products
app = DjangoDash("SimpleExample")
products = Products.objects.all()
to_dic = list(Products.objects.all().values("name", "price"))
keys_are = []
values_are = []
dictionary = {}
for i in to_dic:
keys_are.append(i["name"])
values_are.append(i["price"])
dictionary["name"] = keys_are
dictionary["price"] = values_are
opts = []
for i in to_dic:
opts.append({"label": i["name"], "value": i["price"]})
app.layout = html.Div(
[
html.Div(
children=[
html.Label("Products"),
dcc.Dropdown(id="pid", options=opts, value=values_are[0]),
],
style={"padding": 10, "flex": 1},
),
html.Div(id="gr_container", children=[]),
html.Br(),
dcc.Graph(id="pro_graph", figure={}),
],
)
#app.callback(
[
Output(component_id="pro_graph", component_property="figure"),
Output(component_id="gr_container", component_property="children"),
],
[
Input(component_id="pid", component_property="value"),
],
)
def update_graph(selected):
message = "The option selected is :{}".format(selected)
fig = px.bar(dictionary, x="name", y="price")
return fig, message
if __name__ == "__main__":
app.run_server(debug=True)
this is my dash-graph.py file in django project, when I run the project it show bar on dashboard, but when I update database i.e. the product model it does not update the bar and show the old graph until I run the server again, also the select box is just for testing no use for that here. Also is their a better way write this code, like the dictionary one.
moved it to update_graph function and it works
import plotly.express as px
import pandas as pd
from django_plotly_dash import DjangoDash
from product.models import Products
app = DjangoDash("SimpleExample")
app.layout = html.Div(
[
html.Div(
children=[
html.Label("Products"),
dcc.Dropdown(
id="pid",
),
],
style={"padding": 10, "flex": 1},
),
html.Div(id="gr_container", children=[]),
html.Br(),
dcc.Graph(id="pro_graph", figure={}),
],
)
#app.callback(
[
Output(component_id="pid", component_property="options"),
Output(component_id="pro_graph", component_property="figure"),
Output(component_id="gr_container", component_property="children"),
],
[
Input(component_id="pid", component_property="value"),
],
)
def update_graph(selected):
products = Products.objects.all()
to_dic = list(Products.objects.all().values("pk", "name", "price"))
keys_are = []
values_are = []
dictionary = {}
for i in to_dic:
keys_are.append(i["name"])
values_are.append(i["price"])
opts.append({"label": i["name"], "value": str(i["pk"])})
dictionary["name"] = keys_are
dictionary["price"] = values_are
opts = []
message = "The option selected is :{}".format(selected)
fig = px.bar(dictionary, x="name", y="price")
return opts, fig, message```

How to use Long_callback with multipage app in Dash Plotly?

I'm trying to build a multi page Dash App with Long Callback . When I run the app with Single page Application , it is working fine .Working code is given Below
SinglePage.py
import json
import dash
from dash import html, dcc
from dash.long_callback import DiskcacheLongCallbackManager
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import datetime
import pandas as pd
import plotly.express as px
## Diskcache
import diskcache
from query_4_entity_explr import get_ORG_info, get_daterange_entity_dataframe
cache = diskcache.Cache("./cache")
long_callback_manager = DiskcacheLongCallbackManager(cache)
app = dash.Dash("topx_org",
long_callback_manager=long_callback_manager,
external_stylesheets=[dbc.themes.BOOTSTRAP],
meta_tags=[{'name': 'viewport', 'content': 'initial-scale=1'}])
today = datetime.datetime.today().date()
date_30_day_back = (datetime.datetime.today() - datetime.timedelta(days=1)).date()
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.H3("Explore Organizations mentioned in media", className='text-center text-primary py-5'), width=12)
]),
dbc.Row([
dbc.Col(dbc.Label(['Select daterange']), width={'size': 2, 'offset': 0}),
dbc.Col(dcc.DatePickerRange(id='input_date_picker_range', display_format='YYYY-MM-DD', start_date=date_30_day_back, end_date=today), width={'size':10, 'offset':0}),
], justify='around', className='mb-1'),
dbc.Row([
dbc.Col(dbc.Label(['Choose Companies with mention count']), width=2),
dbc.Col(dcc.Dropdown(id = "input_item_dropdown", options = [], value=[], multi=True), width=10),
], justify='around', className='mb-1'),
# dbc.Row(dbc.Button(id="cancel_button_id", children="Cancel Running Job!")),
dbc.Row([
dbc.Col(html.Div(id="output_text", children=[]), width={'size':10, 'offset':2}),
], justify='around', className='py-3'),
dbc.Row([
html.Progress(id="progress_bar"),
]),
dbc.Row([
dbc.Col(dcc.Graph(id='output_graph', figure={}), width=12),
], justify='around', className='py-5'),
dcc.Store(id='stored-dataframe')
])
#app.long_callback(
[Output(component_id='output_text', component_property='children'),
Output(component_id="input_item_dropdown", component_property="options"),
Output(component_id='stored-dataframe', component_property='data'),
],
[Input(component_id="input_date_picker_range", component_property="start_date"),
Input(component_id="input_date_picker_range", component_property="end_date"),
],
manager=long_callback_manager,
running=[
(Output("output_text", "disabled"), False, True),
(
Output("output_graph", "style"),
{"visibility": "hidden"},
{"visibility": "visible"},
),
(
Output("progress_bar", "style"),
{"visibility": "visible"},
{"visibility": "hidden"},
),
],
)
def update_figure(start_date, end_date):
print(start_date)
print(end_date)
# Data Acquisition
TOP_N = 20
unique_org_list, top_companys, org_gp_pdf = get_ORG_info(get_daterange_entity_dataframe(start_date,end_date), TOP_N)
# For the div
# _text = str(f"Between {start_date} to {end_date} for all the organizations : { ', '.join (item_list_value) }")
_text = str(f"Between {start_date} to {end_date} there are {len(unique_org_list)} organizations mentioned in media.")
# Store the data in browser storage.
datasets = {
'so_1': org_gp_pdf.to_json(orient='split', date_format='iso'),
'so_2': top_companys,
}
return [_text], [{'label': str(c[0]) + f" ({c[1]})", 'value': str(c[0])} for c in unique_org_list[0:]], json.dumps(datasets)
#app.callback(
[Output(component_id='output_graph', component_property='figure')],
[Input(component_id="input_item_dropdown", component_property="value"),
Input(component_id='stored-dataframe', component_property='data')
],
progress=[Output("progress_bar", "value"), Output("progress_bar", "max")],
)
def update_graph_2(item_list_value, jsonified_cleaned_data):
# Load the stored DF and List from Browser storage
datasets = json.loads(jsonified_cleaned_data)
df_2 = pd.read_json(datasets['so_1'], orient='split')
top_companys = datasets['so_2']
if len(item_list_value) == 0:
fig = px.bar( df_2[df_2.ORG.isin(top_companys)].sort_values(['NEWS_DATE'], ascending=True), title=f"Showing top {len(top_companys)} organizations", x="NEWS_DATE", y="COUNT", color="ORG", barmode="group") # .query("ORG=='Mentice' | ORG=='Isofol Medical AB'")
else:
queryString = " | ".join([f"ORG=='{item}'" for item in item_list_value])
fig = px.bar(df_2.query(queryString).sort_values(['NEWS_DATE'], ascending=True) ,title=f"Showing some selected organizations", x="NEWS_DATE", y="COUNT", color="ORG", barmode="group") # .query("ORG=='Mentice' | ORG=='Isofol Medical AB'")
# align title
fig.update_layout(title_x=0.5, xaxis=dict(title_text='NEWS PUBLISH DATE'), yaxis=dict(title_text='DAILY ORG MENTION COUNT '))
return [fig]
if _name_ == "__main__":
app.run_server(port=8050, debug=False)
But When i am trying run the same application in multipage structure it is showing me #long_callback is not callable.
In Multipage structure my main App file is given below
app.py
from pages import topx_org, topx_per
import dash
from dash import html, dcc
from dash.long_callback import DiskcacheLongCallbackManager
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
## Diskcache
import diskcache
cache = diskcache.Cache("./cache")
long_callback_manager = DiskcacheLongCallbackManager(cache)
app = dash.Dash(__name__,
suppress_callback_exceptions=True,
long_callback_manager=long_callback_manager,
external_stylesheets=[dbc.themes.BOOTSTRAP],
meta_tags=[{'name': 'viewport', 'content': 'initial-scale=1'}])
server = app.server
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content')
])
#app.callback(Output('page-content', 'children'),
Input('url', 'pathname'))
def display_page(pathname):
if pathname == '/topx_org':
return topx_org.layout
elif pathname == '/topx_per':
return topx_per.layout
else:
return '404'
if _name_ == '__main__':
app.run_server(debug=True)
and the topx_org.py is given below
from dash import callback, long_callback
import json
from dash import html, dcc
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import datetime
import pandas as pd
import plotly.express as px
from query_4_entity_explr import get_ORG_info, get_daterange_entity_dataframe
today = datetime.datetime.today().date()
date_30_day_back = (datetime.datetime.today() - datetime.timedelta(days=1)).date()
layout = dbc.Container([
dbc.Row([
dbc.Col(html.H3("Explore Organizations mentioned in media", className='text-center text-primary py-5'), width=12)
]),
dbc.Row([
dbc.Col(dbc.Label(['Select daterange' ]), width={'size':2, 'offset':0}),
dbc.Col(dcc.DatePickerRange(id='input_date_picker_range', display_format='YYYY-MM-DD',start_date=date_30_day_back, end_date=today), width={'size':10, 'offset':0}),
], justify='around', className='mb-1'),
dbc.Row([
dbc.Col(dbc.Label(['Choose Companies with mention count']), width=2),
dbc.Col(dcc.Dropdown(id = "input_item_dropdown", options = [], value=[], multi=True), width=10),
], justify='around', className='mb-1'),
dbc.Row([
dbc.Col(html.Div(id="output_text", children=[]), width={'size':10, 'offset':2}),
], justify='around', className='py-3'),
dbc.Row([
dbc.Col(dcc.Graph(id='output_graph', figure={}), width=12),
], justify='around', className='py-5'),
dcc.Store(id='stored-dataframe')
])
# Output(component_id='output_graph', component_property='figure'),
#callback(
[Output(component_id='output_text', component_property='children'),
Output(component_id="input_item_dropdown", component_property="options"),
Output(component_id='stored-dataframe', component_property='data'),
],
[Input(component_id="input_date_picker_range", component_property="start_date"),
Input(component_id="input_date_picker_range", component_property="end_date"),
],
progress=[Output("progress_bar", "value"), Output("progress_bar", "max")],
)
def update_figure(start_date, end_date):
print(start_date)
print(end_date)
# print(item_list_value)
# Data Acquisition
TOP_N = 20
unique_org_list, top_companys, org_gp_pdf = get_ORG_info(get_daterange_entity_dataframe(start_date,end_date), TOP_N)
# For the div
# _text = str(f"Between {start_date} to {end_date} for all the organizations : { ', '.join (item_list_value) }")
_text = str(f"Between {start_date} to {end_date} there are {len(unique_org_list)} organizations mentioned in media.")
# Store the data in browser storage.
datasets = {
'so_1': org_gp_pdf.to_json(orient='split', date_format='iso'),
'so_2': top_companys,
}
return [_text], [{'label': str(c[0]) + f" ({c[1]})", 'value': str(c[0])} for c in unique_org_list[0:]], json.dumps(datasets)
#long_callback(
[Output(component_id='output_graph', component_property='figure')],
[Input(component_id="input_item_dropdown", component_property="value"),
Input(component_id='stored-dataframe', component_property='data')
],
running=[
(Output("output_text", "disabled"), False, True),
(
Output("output_graph", "style"),
{"visibility": "hidden"},
{"visibility": "visible"},
),
(
Output("progress_bar", "style"),
{"visibility": "visible"},
{"visibility": "hidden"},
),
],
)
def update_graph_2(item_list_value, jsonified_cleaned_data):
# Load the stored DF and List from Browser storage
datasets = json.loads(jsonified_cleaned_data)
df_2 = pd.read_json(datasets['so_1'], orient='split')
top_companys = datasets['so_2']
if len(item_list_value) == 0:
fig = px.bar( df_2[df_2.ORG.isin(top_companys)].sort_values(['NEWS_DATE'], ascending=True), title=f"Showing top {len(top_companys)} organizations", x="NEWS_DATE", y="COUNT", color="ORG", barmode="group") # .query("ORG=='Mentice' | ORG=='Isofol Medical AB'")
else:
queryString = " | ".join([f"ORG=='{item}'" for item in item_list_value])
fig = px.bar(df_2.query(queryString).sort_values(['NEWS_DATE'], ascending=True) ,title=f"Showing some selected organizations", x="NEWS_DATE", y="COUNT", color="ORG", barmode="group") # .query("ORG=='Mentice' | ORG=='Isofol Medical AB'")
# align title
fig.update_layout(title_x=0.5, xaxis=dict(title_text='NEWS PUBLISH DATE'), yaxis=dict(title_text='DAILY ORG MENTION COUNT '))
return [fig]
I am having the following error
#long_callback(
TypeError: 'module' object is not callable
(Updated) According to this post, this is not possible yet because long_callback requires the app object (#app.long_callback). If you try to import the app object in your page file, you will create a circular import which will cause an error.
The only possibility mentionned in the post is to put all the long callbacks in the app.py file. The 'normal' callbacks and the layout can stay in the pages files.
This is now possible in the latest dash version by using the function app = dash.get_app() and then calling #app.long_callback.

How to insert several dropdowns in plotly dash

I am trying to get into using Plotly Dash and I am getting stuck on this one piece where I would like to dynamically add a user-defined number of dropdowns. Here is what I tried:
# Import required libraries
import dash
import math
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
# App Begins
app = dash.Dash(
__name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}],
)
app.title = "Tool"
server = app.server
# Create global chart template
mapbox_access_token = "pk.eyJ1IjoicGxvdGx5bWFwYm94IiwiYSI6ImNrOWJqb2F4djBnMjEzbG50amg0dnJieG4ifQ.Zme1-Uzoi75IaFbieBDl3A"
layout = dict(
autosize=True,
automargin=True,
margin=dict(l=30, r=30, b=20, t=40),
hovermode="closest",
plot_bgcolor="#F9F9F9",
paper_bgcolor="#F9F9F9",
legend=dict(font=dict(size=10), orientation="h"),
title="Satellite Overview",
mapbox=dict(
accesstoken=mapbox_access_token,
style="light",
center=dict(lon=-78.05, lat=42.54),
zoom=7,
),
)
# Create app layout
app.layout = html.Div(
[
dcc.Store(id="aggregate_data"),
# empty Div to trigger javascript file for graph resizing
html.Div(id="output-clientside"),
html.Div(
[
html.Div(
[
html.Img(
src=app.get_asset_url("dash-logo.png"),
id="plotly-image",
style={
"height": "60px",
"width": "auto",
"margin-bottom": "25px",
},
)
],
className="one-third column",
),
html.Div(
[
html.Div(
[
html.H3(
"Dash Tool",
style={"margin-bottom": "0px"},
),
]
)
],
className="one-half column",
id="title",
),
],
id="header",
className="row flex-display",
style={"margin-bottom": "25px"},
),
html.Div(
[
html.Div(
[
html.P("Quantity 1:", className="control_label"),
dcc.Input(
id="quantity_1",
type="number",
placeholder=33.
),
html.P("Quantity 2:", className="control_label"),
dcc.Input(
id="quantity_2",
type="number",
placeholder=-115.
),
html.P("Number of Drop Downs:", className="control_label"),
dcc.Slider(
id="drop_downs",
min=2,
max=10,
value=2,
step=1.0,
className="dcc_control",
),
html.P("Load Inputs:", className="control_label"),
dcc.Checklist(
id='sources_flag',
options=[
{'label': 'Yes', 'value': 'Y'},
],
value=['Y'],
labelStyle={'display': 'inline-block'}
),
html.Div(id='source_dropdown_container', children=[]),
html.Div(id='source_dropdown_container_output'),
html.Div(id='source_file_container', children=[]),
html.Div(id='source_file_container_output'),
],
className="pretty_container four columns",
id="cross-filter-options",
),
],
className="row flex-display",
),
],
id="mainContainer",
style={"display": "flex", "flex-direction": "column"},
)
# Create callbacks
#app.callback(
[
Output(component_id='source_dropdown_container_output', component_property='children'),
],
[
Input(component_id='drop_downs', component_property='value'),
Input(component_id='sources_flag', component_property='value'),
]
)
def update_source_dropdowns(value, value_1):
"""Controls the number of drop-downs available to choose sources"""
if value_1 == 'Y':
children = []
for i in range(0, value):
new_dropdown = dcc.Dropdown(
id=f'''source_dropdown_{str(i)}''',
options=['GOOG', 'FB', 'TDOC', 'FANG']
)
children.append(new_dropdown)
print(children)
print(type(children))
return children
I keep running into a callback error. The drop down is constructed properly, so I am kind of confused as to why that error is being invoked.
dash.exceptions.InvalidCallbackReturnValue: The callback ..source_dropdown_container_output.children.. is a multi-output.
Expected the output type to be a list or tuple but got:
None.
Any guidance or help is appreciated. All I am trying to do is add based on user input a dynamic number of drop downs to the layout.
you have three errors in your callback
there is only one return, hence do not define Output as a list
conditional check is wrong, should be if value_1 == ['Y']:
doc.Dropdown() options argument needs to define list of dict
# Create callbacks
#app.callback(
Output(component_id='source_dropdown_container_output', component_property='children'),
[
Input(component_id='drop_downs', component_property='value'),
Input(component_id='sources_flag', component_property='value'),
]
)
def update_source_dropdowns(value, value_1):
"""Controls the number of drop-downs available to choose sources"""
print("cb", value, value_1)
if value_1 == ['Y']:
children = []
for i in range(0, value):
new_dropdown = dcc.Dropdown(
id=f'''source_dropdown_{str(i)}''',
options=[{"label":v, "value":v } for v in ['GOOG', 'FB', 'TDOC', 'FANG']],
)
children.append(new_dropdown)
print(children)
print(type(children))
return children

How can I have multiple Navigations for the same URL paths in Dash

I am trying to add multiple navigations for the same URL path.
my code..
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
app = dash.Dash()
index_layout = html.Div([
# represents the URL bar, doesn't render anything
dcc.Location(id='url', refresh=False),
html.Br(),
dcc.Link(dbc.Button('Page1',
color="secondary",
className="mr-1",
outline=True,
style={"width":400,
"vertical-align": "middle",
}
), href='/page1'),
html.Br(),html.Br(),html.Br(),html.Br(),html.Br(),
dcc.Link(dbc.Button("Page2",
style={"width":400,
"vertical-align": "middle"},
color="secondary",
className="mr-1",
outline=True
), href='/page2'),
])
page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")
app.layout = html.Div([
dcc.Location(id='url-nav', refresh=True),
html.Span(dbc.Nav(
[
dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
dbc.NavLink(dbc.NavLink("Page2", href="/page2")),
],
pills=True,),
className="ml-auto"
),
dcc.Location(id='url', refresh=True),
html.Center([
html.H3('DEMO AP',id='title'),
# content will be rendered in this element
html.Div(id='page-content'),
],),
])
### CALLBACKS
#app.callback(dash.dependencies.Output('page-content', 'children'),
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname="/"):
ctx = dash.callback_context
triggered_by = ctx.triggered[0].get("prop_id")
if pathname == "/page1":
return page1_layout
elif pathname == "/page2":
return page2_layout
else:
return index_layout
if __name__ == "__main__":
app.run_server()
Button navigations are working fine, but html.Nav only works on the very first click, not consistent and not working on the following clicks.
Kindly help.
From testing this out the problem seems to be with this line in index_layout:
dcc.Location(id='url', refresh=False),
If you look in the console you will see that a lot of requests are sent constantly when you're on the main page (when index_layout is rendered).
When this line is removed your code works as expected.
Working solution:
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
app = dash.Dash()
index_layout = html.Div(
[
html.Br(),
dcc.Link(
dbc.Button(
"Page1",
color="secondary",
className="mr-1",
outline=True,
style={
"width": 400,
"vertical-align": "middle",
},
),
href="/page1",
),
html.Br(),
html.Br(),
html.Br(),
html.Br(),
html.Br(),
dcc.Link(
dbc.Button(
"Page2",
style={"width": 400, "vertical-align": "middle"},
color="secondary",
className="mr-1",
outline=True,
),
href="/page2",
),
]
)
page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")
app.layout = html.Div(
[
dcc.Location(id="url-nav", refresh=True),
html.Span(
dbc.Nav(
[
dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
dbc.NavLink(dbc.NavLink("Page2", href="/page2")),
],
pills=True,
),
className="ml-auto",
),
dcc.Location(id="url", refresh=True),
html.Center(
[
html.H3("DEMO AP", id="title"),
# content will be rendered in this element
html.Div(id="page-content"),
],
),
]
)
### CALLBACKS
#app.callback(
dash.dependencies.Output("page-content", "children"),
[dash.dependencies.Input("url", "pathname")],
)
def display_page(pathname="/"):
ctx = dash.callback_context
triggered_by = ctx.triggered[0].get("prop_id")
if pathname == "/page1":
return page1_layout
elif pathname == "/page2":
return page2_layout
else:
return index_layout
if __name__ == "__main__":
app.run_server()
The problem here I think is that there are two Location components rendered at the same time with the same id (url). This apparently causes the callback to be called constantly and causes inconsistent link behavior.

Categories

Resources