How can callback handle variable number of multiple inputs in Dash - python

I would like to develop a program that is able to dynamically compute the mean for different types of distributions (normal, lognormal). The distribution functions require two respectively three input parameters.
My callback returns an: “A nonexistent object was used in an Input …” error since always three input parameters are passed to the function.
Does anyone have an idea how to solve this issue?
Thanks
import dash
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
import pandas as pd
import numpy as np
import scipy.stats as stats
#app = dash.Dash()
app = JupyterDash(external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True)
app.layout = html.Div([
dbc.Card(
dbc.CardBody([
dbc.Row([
dbc.Col([
dbc.Row([
dcc.Dropdown(
id='dd-dist',
clearable = False,
options=[
{'label': 'Normal', 'value': 'NOR'},
{'label': 'Log-Normal', 'value': 'LGN'},
],
style={'width': '60%'},
value='LGN'
)
],),
html.Div(
id='parameter-input'
),
dbc.Row([
dbc.Col([
html.H5('Mean')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='mean-out',
value= None,
)
])
]),
], width={'size': 4, 'offset': 0, 'order': 1}),
], align='center'),
])
)
], style={'padding': 10})
#app.callback(
Output('parameter-input', 'children'),
[Input('dd-dist', 'value')])
def update_parameter(value):
if 'LGN' == value:
return (dbc.Row([
dbc.Col([
html.H5('Shape')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='param1-in',
debounce = True,
value = 1,
min= 0,
max= 10,
style = {'fontSize': 14}
)
],width={'size': 4, 'offset': 0}, align='end')
]),
dbc.Row([
dbc.Col([
html.H5('Location')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='param2-in',
debounce = True,
value = 1,
min=0,
max=5,
style = {'fontSize': 14}
)
],width={'size': 4, 'offset': 0}, align='end')
]),
dbc.Row([
dbc.Col([
html.H5('Scale')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='param3-in',
debounce = True,
value = 1,
min=0,
max=5,
style = {'fontSize': 14}
)
],width={'size': 4, 'offset': 0}, align='end')
])
)
elif 'NOR' == value:
return (dbc.Row([
dbc.Col([
html.H5('Mean')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='param1-in',
debounce = True,
value = 1,
min= 0,
max= 10,
style = {'fontSize': 14}
)
],width={'size': 4, 'offset': 0}, align='end')
]),
dbc.Row([
dbc.Col([
html.H5('Standard deviation')
],width={'size': 5, 'offset': 0}),
dbc.Col([
dcc.Input(
id='param2-in',
debounce = True,
value = 1,
min=0,
max=5,
style = {'fontSize': 14}
)
],width={'size': 4, 'offset': 0}, align='end')
])
)
#app.callback(
Output('mean-out', 'value'),
[Input('dd-dist', 'value'),
Input('param1-in', 'value'),
Input('param2-in', 'value'),
Input('param3-in', 'value')
]
)
def return_mean(dist, param1, param2, param3):
if dist == 'LGN':
return round(stats.lognorm.mean(float(param1), float(param2), float(param3)), 3)
elif dist == 'NOR':
return round(stats.norm.mean(float(param1), float(param2)), 3)
if __name__ == '__main__':
app.run_server(mode='external')

I might be misinterpreting this but it seems to me like you want a varying number of arguments. The proper way to do this in python is this syntax:
def test(*args):
for arg in args:
print(arg)
This function will accept any number of inputs and print them in order as the *args creates a list of all the trailing arguments. It should be noted that positional arguments can still be placed before this and it will not raise an error if it receives no arguments, it only creates an empty list.
Make sure to comment if you have any questions or if this was not what you were asking for.

Related

How to display a Dash table inside an HTML container?

I have a small issue with Dash Table.
What I want to do is to put the table "records" inside the HTML container "graphique3". I have two problems:
First, when I simply want to display the table, nothing appears, it's just a copy/paste of a template here: https://dash.plotly.com/datatable/style. It works when I make a new file though.
Second, if I put my table code inside the container "graphique3" I get this error message
SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?" for data = OrderedDict
I don't understand what is the issue, since, as mentioned before, it works fine in a new file.
# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.
from dash import Dash, html, dcc, dash_table
import plotly.express as px
import pandas as pd
import dash_daq as daq
from collections import OrderedDict
app = Dash(__name__)
# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df = pd.DataFrame({
"Fruit": ["Apples", "Oranges", "Bananas", "test4", "test5", "test6","test7","test8","test9"],
"Amount": [4, 1, 2, 2, 4, 5, 9, 5, 6],
})
fig = px.bar(df, x="Fruit", y="Amount", barmode="group")
#Réduire l'espace entre les éléments
fig.update_layout(
margin=dict(l=5, r=5, t=5, b=5),
paper_bgcolor="white",
),
# Table to put inside the container "graphique4"
data = OrderedDict(
[
("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
("Humidity", [10, 20, 30, 40, 50, 60]),
("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
]
)
df = pd.DataFrame(data)
app = Dash(__name__)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
style_cell_conditional=[
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['Date', 'Region']
],
style_data={
'color': 'black',
'backgroundColor': 'white'
},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(220, 220, 220)',
}
],
style_header={
'backgroundColor': 'rgb(210, 210, 210)',
'color': 'black',
'fontWeight': 'bold'
}
)
app.layout = html.Div(className='dashboard', children=[
# ------ Graphiques --------
#Première row
html.Div(className='row1', style={'display': 'flex', 'justify-content': 'center'}, children=[
# Graphiques
html.Div(className='graphique1',children=[
dcc.Graph(
id='exemple-graph1',
figure=fig,
style={'flex-grow': '1', 'width':'900px'}
),
]),
html.Div(className='graphique2',children=[
dcc.Graph(
id='exemple-graph2',
figure=fig,
style={'flex-grow': '1', 'width':'900px'}
),
]),
]),
# Deuxième row
html.Div(className='row2', style={'display': 'flex', 'justify-content': 'center'}, children=[
# Graphiques
html.Div(className='graphique3', children=[
dcc.Graph(
id='exemple-graph3',
figure=fig,
#style={'display': 'flex', 'width': '500px'}
),
]),
html.Div(className='graphique4', children=[
daq.Gauge(
color={"gradient": True, "ranges": {"green": [0, 6], "yellow": [6, 8], "red": [8, 10]}},
value=2,
label='Temps avant la prochaine relève',
max=10,
min=0,
),
]),
html.Div(className='graphique5', children=[
dcc.Graph(
id='exemple-graph5',
figure=fig,
)
]),
]),
])
if __name__ == '__main__':
app.run_server(debug=True)
#lien tutoriel : https://towardsdatascience.com/dash101-part-2-prettify-dash-dashboard-with-css-and-python-3866c069a3b6
The following code fragment taken from the Dash Tutorial website generates a HTML table.
def generate_table(dataframe, max_rows=10):
return html.Table([
html.Thead(
html.Tr([html.Th(col) for col in dataframe.columns])
),
html.Tbody([
html.Tr([
html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
]) for i in range(min(len(dataframe), max_rows))
])
])
Within your code you then call the function to generate the table and pass the dataframe as a parameter.
html.Div(className='graphique3', children=[
dcc.Graph(
id='exemple-graph3',
figure=fig,
#style={'display': 'flex', 'width': '500px'}
),
generate_table(df)
]),

Divide my dashboard into two columns in Python Dash

I tried now for some time to divide my dashboard into two columns, with "Material1" centered in the first column, and "Material2" centered in the second column, keeping the graph as is (entire width) of this dashboard:
I tried dbc.col and dbc.Row methods to solve this, but haven't found the right way to do this.
Any help is highly appreciated!! :)
This is my code:
app.layout = html.Div([
# Input Row: Material 1
html.Div([
html.Label('Material 1'),
dcc.Dropdown(
id='dropdown1',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-1',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
]),
# Input Row: Material 2
html.Div([
html.Label('Material 2'),
dcc.Dropdown(
id='dropdown2',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-2',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
], style={'display': 'inline-block'}),
# Input: Indicator
html.Div([
html.Label('Indicator'),
dcc.Dropdown(
id='dropdown3',
style={'width': '400px', 'margin-left': 0}),
]),
#Graph
html.Div([
dcc.Graph(
id='display-selected-values',
style={'width': '2400px', 'margin-left': 0, 'columnCount': 1}),
])
])
it's all about being systematic (where code formatters help)
using dash 2.0.0 and dbc 1.0.0-b1
keep on embedding Row and Col as required to meet your layout requirements
import json
import numpy as np
import dash_bootstrap_components as dbc
import dash
from jupyter_dash import JupyterDash
all_options = {k: v for k, v in zip(list("ABCD"), np.random.randint(1, 4, 4))}
options1 = list(all_options.keys())
# Build App
app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dash.html.Div(
[
dbc.Row(
[
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 1"),
dash.dcc.Dropdown(
id="dropdown1",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 2"),
dash.dcc.Dropdown(
id="dropdown2",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
],
justify="center",
),
dash.dcc.Graph(id="newCases", style={"height": "45vh"}),
],
style={"font-family": "Arial", "font-size": "0.9em", "text-align": "center"},
)
# Run app and display result inline in the notebook
app.run_server(mode="inline")

Invalid prop for this component

I'm running this app using Python Dash .I keep getting this error even though the app is loading for me perfectly. Can you please help me spot where I'm going wrong?
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go
from dash.dependencies import Input, Output
import plotly.express as px
df = px.data.tips()
sales1 = pd.read_csv("sales_data_sample.csv", encoding='unicode_escape')
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([
html.Label('Process Monitoring Dashboard',style={'font-size':'25px','color':'blue','margin-left': '50%'},id='w_countries')
]),
html.P("Process End Date",style={'margin-left': '10%'}),
dcc.Dropdown(
id='ped',
value='-Select Process End Date',
options=[{'value': x, 'label': x}
for x in ['2021', '2022', '2023', '2024']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("User Or Role",style={'margin-left': '10%'}),
dcc.Dropdown(
id='uor',
value='-Select User Or Role',
options=[{'value': x, 'label': x}
for x in ['Admin', 'Guest User']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("Process Start Date",style={'margin-left': '10%'}),
dcc.Dropdown(
id='psd',
value='-Select Process Start Date',
options=[{'value': x, 'label': x}
for x in ['2021', '2022', '2023', '2024']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("Process",style={'margin-left': '10%'}),
dcc.Dropdown(
id='p',
value='-Select Process',
options=[{'value': x, 'label': x}
for x in ['Disputed','In Process','On Hold','Resolved','Cancelled']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
# Create pie chart
html.Div([
html.Br(),
dcc.Graph(id='pie',
config={'displayModeBar': 'hover'}),
],style={'margin-left': '1.4%', 'width': '50%', 'display': 'inline-block'}),
# Create horizontal bar chart (top 10 countries)
html.Div([
html.Br(),
dcc.Graph(id='top_10',
config={'displayModeBar': 'hover'}),
], style={'width': '48.6%', 'display': 'inline-block', 'float': 'right'})
])
#app.callback(Output('pie', 'figure'),
[Input('w_countries', 'value')])
def display_content(w_countries):
Cancelled = sales1.loc[sales1['STATUS'] == 'Cancelled'].count()[0]
Disputed = sales1.loc[sales1['STATUS'] == 'Disputed'].count()[0]
In_Process = sales1.loc[sales1['STATUS'] == 'In Process'].count()[0]
On_Hold = sales1.loc[sales1['STATUS'] == 'On Hold'].count()[0]
Resolved = sales1.loc[sales1['STATUS'] == 'Resolved'].count()[0]
Shipped = sales1.loc[sales1['STATUS'] == 'Shipped'].count()[0]
return {
'data': [go.Pie(labels=['Cancelled', 'Disputed', 'In Process', 'On Hold', 'Resolved', 'Shipped'],
values=[Cancelled, Disputed, In_Process, On_Hold, Resolved, Shipped],
hoverinfo='label+value+percent',
textinfo='label+value',
textposition='auto',
textfont=dict(size=13),
insidetextorientation='radial',
rotation=70,
)],
'layout': go.Layout(
width=780,
height=520,
hovermode='closest',
title={
'text': 'Instance By Process',
'y': 0.93,
'x': 0.43,
'xanchor': 'center',
'yanchor': 'top'},
titlefont={'family': 'Oswald',
'color': 'rgb(230, 34, 144)',
'size': 25},
legend={
'orientation': 'h',
'bgcolor': 'rgba(255,255,255,0)',
'xanchor': 'center', 'x': 0.5, 'y': -0.05},
),
}
# Create horizontal bar chart (top 10 countries)
#app.callback(Output('top_10', 'figure'),
[Input('w_countries', 'value')])
def update_graph(w_countries):
top_countries = sales1.groupby(['COUNTRY'])[['SALES', 'QUANTITYORDERED']].sum().sort_values(by=['SALES'], ascending=False).nlargest(10, columns=['SALES']).reset_index()
return {
'data': [go.Bar(x=top_countries['SALES'],
y=top_countries['COUNTRY'],
text=top_countries['SALES'],
texttemplate='%{text:.2s}',
textposition='inside',
marker=dict(
color=top_countries['SALES'],
colorscale='portland',
showscale=False),
orientation='h',
hoverinfo='text',
hovertext=
'<b>Country</b>: ' + top_countries['COUNTRY'].astype(str) + '<br>' +
'<b>Sales</b>: $' + [f'{x:,.0f}' for x in top_countries['SALES']] + '<br>' +
'<b>Q.Ordered</b>: $' + [f'{x:,.0f}' for x in top_countries['QUANTITYORDERED']] + '<br>'
)],
'layout': go.Layout(
width=780,
height=520,
# plot_bgcolor='rgb(250, 242, 242)',
# paper_bgcolor='rgb(250, 242, 242)',
title={
'text': 'Top 10 Countries with active customers',
'y': 0.93,
'x': 0.43,
'xanchor': 'center',
'yanchor': 'top'},
titlefont={'family': 'Oswald',
'color': 'rgb(230, 34, 144)',
'size': 25},
hovermode='closest',
xaxis=dict(title='<b>Sales</b>',
color='rgb(230, 34, 144)',
showline=True,
showgrid=True,
showticklabels=True,
linecolor='rgb(104, 204, 104)',
linewidth=2,
ticks='outside',
tickfont=dict(
family='Arial',
size=12,
color='rgb(17, 37, 239)'
)
),
yaxis=dict(title='<b>Country</b>',
autorange='reversed',
color='rgb(230, 34, 144)',
showline=True,
showgrid=False,
showticklabels=True,
linecolor='rgb(104, 204, 104)',
linewidth=2,
ticks='outside',
tickfont=dict(
family='Arial',
size=12,
color='rgb(17, 37, 239)'
)
)
)
}
if __name__ == '__main__':
app.run_server(debug=True)
And this is my error
Invalid prop for this component
Property "value" was used with component ID:
"w_countries"
in one of the Input items of a callback.
This ID is assigned to a dash_html_components.Label component
in the layout, which does not support this property.
This ID was used in the callback(s) for Output(s):
pie.figure
top_10.figure
You've told Dash to use the value from a Label component as an input for your callback. But Label doesn't have a value, and it isn't interactive like that. You need to use a different input for that callback.

Align the dash app layout input box with drop down and dates

I am trying to create a layout using the DASH app, and I am not sure why it's not working when I am trying to set the input boxes with a drop-down.
here is my layout:
tab_1_layout = html.Div([
dcc.Input(id="ad_account_id", type="text", placeholder="Account ID", style={'width': '200px',
'margin-top': 10,
'margin-left': 20,
}),
# html.Br(),
dcc.Input(id="app_id", type="text", placeholder="App ID", style={'width': '200px',
'margin-left': 20,
'display': 'inline-block'
}),
# html.Br(),
dcc.Input(id="access_token", type="text", placeholder="Access Token", style={'width': '200px',
'margin-left': 20,
'display': 'inline-block'
}),
# html.Br(),
dcc.Input(id="app_secret", type="text", placeholder="App Secret", style={'width': '200px',
'margin-left': 20,
}),
# html.Br(),
dcc.Dropdown(
id='dimensions',
options=[{'label': i, 'value': i} for i in ['Campaign', 'Placement', 'Creative']],
multi=True,
placeholder='Dimensions',
style={'width': '200px', 'margin-left': 150, 'margin-top': 20, 'display':'inline-block'}
),
# html.Br(),
dcc.Dropdown(
id='metrics',
options=[{'label': i, 'value': i} for i in ['Impressions', 'Clicks', 'Conversions']],
multi=True,
placeholder='Metrics',
style={'width': '200px', 'margin-left': 400}
),
html.Br(),
dcc.DatePickerSingle(
id='start-date',
placeholder="Start Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '200px', 'margin-top': 10, 'margin-left': 400}
),
# html.Br(),
dcc.DatePickerSingle(
id='end-date',
placeholder="End Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '200px', 'margin-top': 10, 'margin-left': 220}
),
html.Br(),
html.Button(id='submit-button', type='submit', children='Submit', style={'width': '200px', 'margin-top': 10,
'margin-left': 10}),
html.Div(id='output_div')]),
its shwoing the UI like below but i want to align dimension and metrics with first row and then on second row align start date and end date and third row will be submit.
There are a number of ways to achieve this but personally I like Dash Bootstrap layout. Below is your code refactored to use bootstrap rows and columns to achieve what you want. Bootstrap layout
import datetime
import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import dash_html_components as html
import numpy as np
app = dash.Dash(external_stylesheets = [dbc.themes.BOOTSTRAP])
app.title = "Steepest Descent"
server = app.server
row1 = html.Div(
[
dbc.Row([
dbc.Col([
dbc.Input(id="ad_account_id",
type="text",
placeholder="Account ID",
style={'width': '150px'}),
], width={"order": "first"}),
dbc.Col([
dbc.Input(id="app_id",
type="text",
placeholder="App ID",
style={'width': '150px'}),
]),
dbc.Col([
dbc.Input(id="access_token",
type="text",
style={'width': '150px'},
placeholder="Access Token")
]),
dbc.Col([
dbc.Input(id="app_secret",
type="text",
style={'width': '150px'},
placeholder="App Secret")
]),
dbc.Col([
dcc.Dropdown(
id='dimensions',
options=[{'label': i, 'value': i} for i in ['Campaign', 'Placement', 'Creative']],
multi=True,
style={'width': '150px'},
placeholder='Dimensions')
]),
dbc.Col([
dcc.Dropdown(
id='metrics',
options=[{'label': i, 'value': i} for i in ['Impressions', 'Clicks', 'Conversions']],
multi=True,
style={'width': '150px'},
placeholder='Metrics')
])
], align="center"),
]
)
row2 = html.Div([
dbc.Row([
dbc.Col([
dcc.DatePickerSingle(
id='start-date',
placeholder="Start Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '150px'}
),
], width={"order": "first"}),
dbc.Col([
# html.Br(),
dcc.DatePickerSingle(
id='end-date',
placeholder="End Date",
min_date_allowed=datetime.datetime.now().strftime('2018-01-01'),
max_date_allowed=datetime.datetime.today().date(),
display_format='YYYY-MM-DD',
style={'width': '150px'}
)], align="center"),
])
])
row3 = html.Div([
dbc.Row([
dbc.Col([
html.Button(id='submit-button', type='submit', children='Submit', style={'width': '200px', 'margin-top': 10,
'margin-left': 10}),
], width={"order": "first"}),
dbc.Col([
html.Div(id='output_div'),
])
])
])
app.layout = dbc.Container(children=[
row1,
html.Br(),
row2,
html.Br(),
row3]
)
if __name__ == '__main__':
app.run_server(debug=True)

Pandas 'key' error while creating charts through Dash

I am trying to create a scatter plot between two metrics after asking for the dimension level drill down. However, I am getting the the error: KeyError: u’brand’(one of the column names). I am new do Dash and cannot debug the error because there is nothing wrong with the column name. Following is the code:
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
import sqlalchemy as sq
import numpy as np
from datetime import datetime
engine_prd = sq.create_engine(“connection url”)
df=pd.read_sql(“SELECT t1.date,
t1.article_type as article_type,
t1.product_gender as product_gender,
t1.brand as brand,
t1.master_category as master_category,
t1.business_unit as business_unit,
SUM(t1.revenue) as revenue,
SUM(t1.sold_quantity) as units_sold,
SUM(t1.total_discount) / NULLIF( SUM(t1.total_mrp),0) AS discount_perc,
SUM(t1.approved_po_quantity) - SUM(t1.po_inwarded_quantity) AS pending_invard_quantity,
SUM(t1.revenue) / NULLIF(SUM(t1.list_count), 0) AS rpi,
SUM(t1.list_count),
100 *ratio_to_report(SUM(t1.list_count)) OVER (PARTITION BY t1.DATE) AS lc_share
FROM fact_category_over_view_metrics t1
WHERE t1.DATE> 20180101 and is_live_style=1
GROUP BY
t1.DATE,t1.article_type,t1.product_gender,t1.brand,t1.master_category,
t1.business_unit;”,engine_prd)
df[[‘date_format’]] = df[[‘date’]].applymap(str).applymap(lambda s: “{}/{}/{}”.format(s[4:6],s[6:], s[0:4]))
df[[‘year_month’]]=df[[‘date’]].applymap(str).applymap(lambda s: “{}-{}”.format(s[0:4],s[4:6]))
df[‘year_month’]=df[‘year_month’].astype(str)
year_month=df[‘year_month’].unique()
available_indicators = np.array([‘revenue’,‘units_sold’,‘discount_perc’,‘pending_invard_quantity’,‘rpi’,‘lc_share’])
dimension_level=np.array([‘brand’,‘product_gender’,‘article_type’,‘master_category’,‘business_unit’])
#available_indicators=list(df)
app=dash.Dash()
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(
id='dimension-level',
options=[{'label': i, 'value': i} for i in dimension_level],
value='brand'
)]),
html.Div([
dcc.Dropdown(
id='crossfilter-xaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='revenue'
),
dcc.RadioItems(
id='crossfilter-xaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
],
style={'width': '48%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
id='crossfilter-yaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='units_sold'
),
dcc.RadioItems(
id='crossfilter-yaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
], style={'width': '48%', 'float': 'right', 'display': 'inline-block'})
]),
dcc.Graph(
id='crossfilter-indicator-scatter'),
dcc.Slider(
id='crossfilter-year-month--slider',
min=0,
max=len(df['year_month'].unique()),
value=0,
step=None,
marks={i : str(yearm) for i, yearm in enumerate(df['year_month'].unique())} # enumerate the dates
)
])
#app.callback(
dash.dependencies.Output(‘crossfilter-indicator-scatter’, ‘figure’),
[dash.dependencies.Input(‘dimension-level’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-year-month–slider’, ‘value’)],
[dash.dependencies.State(‘crossfilter-year-month–slider’, ‘marks’)])
def update_graph(dimension_level_name,xaxis_column_name, yaxis_column_name,xaxis_type, yaxis_type, selected_year_month_key,marks):
selected_year_month=marks[str(selected_year_month_key)]
df_filtered = df[df['year_month'] == selected_year_month]
dff=df_filtered.groupby([dimension_level_name]).sum()
return {
'data': [go.Scatter(
x=dff[xaxis_column_name],
y=dff[yaxis_column_name],
text=dff[dimension_level_name],
#customdata=dff['article_type'],
mode='markers',
marker={
'size': 15,
'opacity': 0.5,
'line': {'width': 0.5, 'color': 'white'}
}
)],
'layout': go.Layout(
xaxis={
'title': xaxis_column_name,
'type': 'linear' if xaxis_type == 'Linear' else 'log'
},
yaxis={
'title': yaxis_column_name,
'type': 'linear' if yaxis_type == 'Linear' else 'log'
},
margin={'l': 40, 'b': 30, 't': 10, 'r': 0},
height=450,
hovermode='closest'
)
}
if name == ‘main’:
app.run_server()
The errors occurs while grouping by the df using the input value from dropdown. The data frame’s head looks has been linked to The sample data:
The key error occurs in "text=dff[dimension_level_name]". It is because while grouping by the dataframe , as_index is not set to False. This will throw a key error. The problem was solved by replacing dff=df_filtered.groupby([dimension_level_name]).sum() with:
dff=df_filtered.groupby([dimension_level_name].as_index=False).sum()

Categories