Unable to replicate a simple chart from plotly into dash. Dash not showing any warning or error signs

Hi All

I am unable to replicate a simple plotly chart into dash.

Pls let me know if anything is unclear as English is not my first language.

Concept behind the chart
I have two parameters units of SKU A and SKU B. these two can be changed to estimate the total cost at different levels.

Usually when dash is unable to make up a chart it gives some clues regarding why there is an empty chart. However there is no error or warning.

df_fixed table which is used in running the file

The fixed ratio column distributes the expense amount across different activities in the ratio of Expense typep. So Variable Exp 1 will be split across Acitvity 1 to 7 based on the Fixed ratio column

Month Expense Type Expense Amt Category Activity Fixed Ratio SKU A SKU B Standard Hours Rate
1/1/2021 Fixed Exp 1 3072000 Fixed Activity 1 1 0.6 1 50000 279.7
1/1/2021 Variable Exp 1 3000000 Variable Activity 1 0.09009009 0.6 1 50000 279.7
1/1/2021 Variable Exp 1 3000000 Variable Activity 2 0.135135135 0.4 1 40000 221.1
1/1/2021 Variable Exp 1 3000000 Variable Activity 3 0.18018018 0.2 3 70000 135.5
1/1/2021 Variable Exp 1 3000000 Variable Activity 4 0.225225225 0.4 2.5 70000 156.5
1/1/2021 Variable Exp 1 3000000 Variable Activity 5 0.27027027 0.4 0.5 30000 450
1/1/2021 Variable Exp 1 3000000 Variable Activity 6 0.09009009 0.16 0.25 13000 584.3
1/1/2021 Variable Exp 1 3000000 Variable Activity 7 0.009009009 0.4 0.75 35000 183.4

Code which works fine on plotly Jupyter

import plotly.graph_objects as go
import pandas as pd
import json
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash_table
import dash_bootstrap_components as dbc
from datetime import date
from app import app
import plotly.express as px
import plotly.graph_objs as go
from random import randint
import math
from math import log
import base64
import numpy as np
from plotly.subplots import make_subplots
# needed only if running this as a single page app
external_stylesheets = [dbc.themes.LUX]


# app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
pd.set_option('precision', 0)
#read the CSV file

df_fixed = pd.read_csv('file_name_ex.csv')

#SKU A and SKU B. I want to vary these in the dashboard
A_unit =50000
B_unit =20000

df_fixed['SKU A hrs'] = df_fixed['SKU A']*A_unit
df_fixed['SKU B hrs'] = df_fixed['SKU B']*B_unit
df_fixed['total hrs'] = df_fixed['SKU A hrs']+df_fixed['SKU B hrs']
df_fixed['rel_hrs'] = df_fixed['total hrs']/df_fixed['Standard Hours']


df_fixed.loc[df_fixed['Category'] == 'Fixed', 'SKU A OH incurred'] = df_fixed['Expense Amt']*df_fixed['Fixed Ratio']*df_fixed['SKU A hrs']/df_fixed['total hrs']
df_fixed.loc[df_fixed['Category'] == 'Variable', 'SKU A OH incurred'] = df_fixed['Expense Amt']*df_fixed['Fixed Ratio']*df_fixed['SKU A hrs']/df_fixed['total hrs']*df_fixed['rel_hrs']

df_fixed.loc[df_fixed['Category'] == 'Fixed', 'SKU B OH incurred'] = df_fixed['Expense Amt']*df_fixed['Fixed Ratio']*df_fixed['SKU B hrs']/df_fixed['total hrs']
df_fixed.loc[df_fixed['Category'] == 'Variable', 'SKU B OH incurred'] = df_fixed['Expense Amt']*df_fixed['Fixed Ratio']*df_fixed['SKU B hrs']/df_fixed['total hrs']*df_fixed['rel_hrs']
df_fixed['Total OH Incurred'] = df_fixed['SKU A OH incurred']+df_fixed['SKU B OH incurred']


df_absorbed = df_fixed

df_absorbed = df_absorbed.drop(['SKU B OH incurred','SKU A OH incurred','rel_hrs','Standard Hours',
                                'SKU B','SKU A','Fixed Ratio','Category',
                                'Expense Amt','Expense Type','Total OH Incurred'],axis=1)

df_absorbed['SKU A OH absorbed']=df_absorbed['Rate']*df_absorbed['SKU A hrs']
df_absorbed['SKU B OH absorbed']=df_absorbed['Rate']*df_absorbed['SKU B hrs']

df_absorbed = pd.DataFrame.drop_duplicates(df_absorbed)

df_absorbed['Total OH absorbed']=df_absorbed['SKU A OH absorbed']+df_absorbed['SKU B OH absorbed']

df_ohi = df_fixed.groupby(['Month'],as_index=False)['Total OH Incurred'].sum()
df_oha = df_absorbed.groupby(['Month'],as_index=False)['Total OH absorbed'].sum()

fig = go.Figure()
fig.add_trace(go.Bar(
    x=df_ohi['Month'],
    y=df_ohi['Total OH Incurred'],
    name='Overheads incurred',
    marker_color='indianred'
))

fig.add_trace(go.Bar(
    x=df_oha['Month'],
    y=df_oha['Total OH absorbed'],
    name='Overheads Absorbed',
    marker_color='indianred'
))

fig.update_layout(barmode='group', xaxis_tickangle=-45)
fig.show()

Here is the code which I use to make a dashboard. I am using spyder so at the end of the code I have to set app.run_server(host=‘127.0.0.1’, debug=False). You may have to change it to True in your case

I have set parameters in the callback as A_unit and B_unit which I want to make dynamic

# Read the df_fixed table first from the above section

#desinging the  dashboard layout
app.layout =html.Div([
        dbc.Row(
            [
                dbc.Col(dbc.Card(html.H1(children='Overheads Absorption Dashboard',
                                 className="text-left text-light bg-dark"), body=True, color="dark")
        , className="mt-4 mb-4",width={'size':12}),
            ],no_gutters=True
            ),       
        dbc.Row(dbc.Col(html.H3("Scenario Analysis Dimensions",
                                className='text-primary font-weight-bolder'),
                        className="mt-4 mb-4, text-left",
                        width={'size': 10, 'offset':1},
                        ),
             ),
         dbc.Row(
            [
                dbc.Col(html.P("SKU A"),
                        width=2
                        ),
                dbc.Col(html.P("SKU B"),
                        width=2
                        ),
                ], no_gutters=False, justify='center', className="text-black"
        ),
         dbc.Row(
            [
                dbc.Col(dcc.Input(id="SKU_A", type="number", placeholder="SKU A",value=1,
                        # style={'backgroundColor': '#000000','color': '#FFFFFF'}
                        ),
                        width=2,
                        ),
                dbc.Col(dcc.Input(id="SKU_B", type="number", placeholder="SKU B",value=1,
                                  # style={'backgroundColor': '#000000','color': '#FFFFFF'}
                                  ),
                        width=2
                        ),
                ], no_gutters=False,justify='center'
        ),
         dbc.Row(
            [
                dbc.Col(dbc.Card(html.H3(children='Scenario Analysis',
                                  className="text-left text-light bg-dark"), body=True, color="dark")
        , className="mt-4 mb-4"),
                dbc.Col(dcc.Graph(id='Scenario_Analysis',
                                  className='text-primary font-weight-bolder'),
                        width={'size':12,'offset':0}, #lg={'size': 6,  "offset": 0, 'order': 'first'}
                        ),
                ]
            ),                
            ]
        )

#App Callback
@app.callback(
    (Output('Scenario_Analysis', 'figure')),
       #Input('SKU_List', 'value') ,
       [Input('SKU_A', 'value'),
       Input('SKU_B', 'value'),
       ]
    )
def scenario(A_unit, B_unit):
    
    df_fixed_p = df_fixed
    df_fixed_p['SKU A hrs'] = df_fixed_p['SKU A']*A_unit
    df_fixed_p['SKU B hrs'] = df_fixed_p['SKU B']*B_unit
    df_fixed_p['total hrs'] = df_fixed_p['SKU A hrs']+df_fixed_p['SKU B hrs']
    df_fixed_p['rel_hrs'] = df_fixed_p['total hrs']/df_fixed_p['Standard Hours']
    
   
    df_fixed_p.loc[df_fixed['Category'] == 'Fixed', 'SKU A OH incurred'] = df_fixed_p['Expense Amt']*df_fixed_p['Fixed Ratio']*df_fixed_p['SKU A hrs']/df_fixed_p['total hrs']
    df_fixed_p.loc[df_fixed['Category'] == 'Variable', 'SKU A OH incurred'] = df_fixed_p['Expense Amt']*df_fixed_p['Fixed Ratio']*df_fixed_p['SKU A hrs']/df_fixed_p['total hrs']*df_fixed_p['rel_hrs']
    
    df_fixed_p.loc[df_fixed['Category'] == 'Fixed', 'SKU B OH incurred'] = df_fixed_p['Expense Amt']*df_fixed_p['Fixed Ratio']*df_fixed_p['SKU B hrs']/df_fixed_p['total hrs']
    df_fixed_p.loc[df_fixed['Category'] == 'Variable', 'SKU B OH incurred'] = df_fixed_p['Expense Amt']*df_fixed_p['Fixed Ratio']*df_fixed_p['SKU B hrs']/df_fixed_p['total hrs']*df_fixed_p['rel_hrs']
    df_fixed_p['Total OH Incurred'] = df_fixed_p['SKU A OH incurred']+df_fixed_p['SKU B OH incurred']
    
    
    df_absorbed = df_fixed_p
    
    df_absorbed = df_absorbed.drop(['SKU B OH incurred','SKU A OH incurred','rel_hrs','Standard Hours',
                                    'SKU B','SKU A','Fixed Ratio','Cost Grouping','Category','Driver',
                                    'Expense Amt','Expense Type','Total OH Incurred'],axis=1)
    
    df_absorbed['SKU A OH absorbed']=df_absorbed['Rate']*df_absorbed['SKU A hrs']
    df_absorbed['SKU B OH absorbed']=df_absorbed['Rate']*df_absorbed['SKU B hrs']
    
    df_absorbed = pd.DataFrame.drop_duplicates(df_absorbed)
    
    df_absorbed['Total OH absorbed']=df_absorbed['SKU A OH absorbed']+df_absorbed['SKU B OH absorbed']
    #df_absorbed.to_csv('file_name.csv', index=False)
    
    df_ohi = df_fixed_p.groupby(['Month'],as_index=False)['Total OH Incurred'].sum()
    df_oha = df_absorbed.groupby(['Month'],as_index=False)['Total OH absorbed'].sum()
    
    fig = go.Figure()
    fig.add_trace(go.Bar(
        x=df_ohi['Month'],
        y=df_ohi['Total OH Incurred'],
        name='Overheads incurred',
        marker_color='indianred'
    ))
    
    fig.add_trace(go.Bar(
        x=df_oha['Month'],
        y=df_oha['Total OH absorbed'],
        name='Overheads Absorbed',
        marker_color='indianred'
    ))
    
    return fig
    
# needed only if running this as a single page app
if __name__ == '__main__':
    app.run_server(host='127.0.0.1', debug=False)

Can someone help me see what I am missing

Hi @shiman

I’m not an expert in graphics but I think you are not passing the fig.update_layout( … )

Also, I use a different way of bilding the ‘figure’ to my bar graphics, here is an example that I used in my app, perhaps it helps:

figure = {"data": [go.Bar(x=rep_ar.index, y=rep_ar.Buy, text=rep_ar.Buy, textposition='auto',
                             marker={"color": "Green", "line": {"color": "white", "width": 1}}, name="Buy"), 
                   go.Bar(x=rep_ar.index, y=rep_ar.Overweight, text=rep_ar.Overweight , textposition='auto',
                             marker={"color": "LightGreen", "line": {"color": "white", "width": 1}}, name="Overweight"),
                   go.Bar(x=rep_ar.index, y=rep_ar.Hold, text=rep_ar.Hold, textposition='auto',
                             marker={"color": "blue", "line": {"color": "white", "width": 1}}, name="Hold"),
                   go.Bar(x=rep_ar.index, y=rep_ar.Underweight, text=rep_ar.Underweight, textposition='auto',
                             marker={"color": "Gold", "line": {"color": "white", "width": 1}}, name="Underweight"), 
                   go.Bar(x=rep_ar.index, y=rep_ar.Sell, text=rep_ar.Sell, textposition='auto',
                             marker={"color": "red", "line": {"color": "white", "width": 1}}, name="Sell")],
         "layout": go.Layout(autosize=True, title= name+' - Analysts Recomendation', height=200, barmode="group",
                               margin={"r": 0,"t": 25,"b": 20,"l": 20}, font={"family": "Raleway", "size": 10},       
                     )}

Thanks for the response.

I tried both the solutions. However none of it worked. Generally when it pops an empty fig, it says the reason for it. But python is not showing any of it.

Also, is there any way to check what values the dataframes inside the callback function are taking. For example, over here I have created a temp df 'df_fixed_p ’ to store the values. I am thinking that maybe the df is empty and hence no chart is coming up.

There is no problem with code. For some reason, if I restart the kernel, I am able to see the chart. But now everytime I re-run the code, I need to restart Jupyter notebook to see the changes. Sad life :frowning:

Hi @shiman

Check if you are not using the same variable name and assigning it different values during the process, if you don’t restart the kernel the variable has the last value you assigned to it. The same can happend to any other elements. Other option is start the code assigning [ ] to everything.