Completion percentage by Pie chart

I’m trying to make Pie charts to show completion percentage and I have a problem about that. Below is my code:

import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
import dash_bootstrap_components as dbc
    
df = pd.DataFrame({'Branch': ['NY','NY','NY','LA','LA','LA','IO','IO','IO'],
                'Name': ['Sales','Card','Loan','Sales','Card','Loan','Sales','Card','Loan'],
                'KPI': [1000,1200,8000,1000,1200,8000,1000,1200,8000],
                'Complete' : [890,1015,7105,780,1120,7600,815,1150,6800]})
df['Percent'] = ((df['Complete']/df['KPI'])*100).round(decimals=2)
    
from plotly.subplots import make_subplots
app = dash.Dash(__name__,external_stylesheets=[dbc.themes.LUX])

app.layout = html.Div([
        dbc.Row(dbc.Col(
            html.H2('KPI Subplots',className='text-center text primary, p-2'))),
        dbc.Row([
            dbc.Col([
                html.H5('Sales KPI',className='text-center'),
                dcc.Graph(id='kpi',figure={}),
                ],width={'size':6,"offset":0,'order':1}),               
            dbc.Col([
                html.H5('Drop Down',className='text-center'),
                dcc.Dropdown(id='br_cd_2',placeholder="Please select branch code",
                                options=[{'label':x,'value':x} for x in df.sort_values('Branch')['Branch'].unique()],
                                value='Select',
                                multi=False,
                                disabled=False,
                                clearable=True,
                                searchable=True),
                    ],width={'size':6,"offset":0,'order':1})
        ],className='p-2'),

])

@app.callback(
        Output(component_id='kpi',component_property='figure'),
        [Input(component_id='br_cd_2',component_property='value')])

def build_graph(branch_cd):
    global dff
    if not branch_cd or 'Select' in branch_cd:
        dff = df[(df['Name']=="Sales")]
        dff = pd.pivot_table(dff,('KPI','Complete'),index=['Name',],aggfunc=np.sum).reset_index()
        dff['Percent'] = ((dff['Complete']/dff['KPI'])*100).round(decimals=2)
        val=dff.iloc[0,3]

        dff2 = df[(df['Name']=="Card")]
        dff2 = pd.pivot_table(dff2,('KPI','Complete'),index=['Name',],aggfunc=np.sum).reset_index()
        dff2['Percent'] = ((dff2['Complete']/dff2['KPI'])*100).round(decimals=2)
        val2=dff2.iloc[0,3]

        dff3 = df[(df['Name']=="Loan")]
        dff3 = pd.pivot_table(dff3,('KPI','Complete'),index=['Name',],aggfunc=np.sum).reset_index()
        dff3['Percent'] = ((dff3['Complete']/dff3['KPI'])*100).round(decimals=2)
        val3=dff3.iloc[0,3]
    
    else:
        dff = df[(df['Branch']== branch_cd)]#.isin(branch_cd)
        dff = dff[(dff['Name']=='Sales')]
        val=dff.iloc[0,4]
        
        dff2 = df[(df['Branch']== branch_cd)]#.isin(branch_cd)
        dff2 = dff2[(dff2['Name']=='Card')]
        val2=dff2.iloc[0,4]    

        dff3 = df[(df['Branch']== branch_cd)]#.isin(branch_cd)
        dff3 = dff3[(dff3['Name']=='Loan')]
        val3=dff3.iloc[0,4]        
        
    fig = make_subplots(rows=1, 
                        cols=3,
                        specs=[[{"type": "pie"}, {"type": "pie"}, {"type": "pie"}]],
                        subplot_titles=("Sales KPI", "Card KPI", "Loan KPI"))
    
    fig.add_trace(go.Pie(labels=['',''],
                          values=[val,100-val],
                          hole=0.8,
                          textinfo='none',
                          marker_colors=['rgb(113,209,145)','rgb(240,240,240)'],
                          ),row=1, col=1),
    
    fig.add_trace(go.Pie(labels=['',''],
                          values=[val2,100-val2],
                          hole=0.8,
                          textinfo='none',
                          marker_colors=['rgb(113,209,145)','rgb(240,240,240)'],
                          ),row=1, col=2),
        
    fig.add_trace(go.Pie(labels=['',''],
                          values=[val3,100-val3],
                          hole=0.8,
                          textinfo='none',
                          marker_colors=['rgb(113,209,145)','rgb(240,240,240)'],
                          ),row=1, col=3),     
        
    fig.add_annotation(x=0.06, y=0.5,
            text=str(val)+"%",
            showarrow=False,
            font_size=20)
    fig.add_annotation(x=0.5, y=0.5,
            text=str(val2)+"%",
            showarrow=False,
            font_size=20)
    fig.add_annotation(x=0.94, y=0.5,
            text=str(val3)+"%",
            showarrow=False,
            font_size=20)    
    fig.update_traces(showlegend=False)
    return fig

if __name__ == "__main__":
    app.run_server(debug=False,port=8057)

Actually it working well and below is the result:

But when completion percentage is over 100% it will not show properly. Some thing like below:

So I’m curious is there anyway to fix it. If completion percentage is over 100%, over part will be faded.

Thank for your help.

Could you define the overage as a percent to chart?

Or, you could just max out at 100%? And show the actual percentage in the annotations like you are now.

1 Like

Hi @jinnyzor

As the second pic, if it over 100%, graph looks weird. So I want to find the way to show over perce ntage on graph (Ex: 115%, over percentage: 15%). If it’s impossible maybe full circle and add annotation as 115% is acceptable option, I think.

Graph the 85% as completed and 15% as overage was what I was thinking.

And instead of just 100%, do a remainder of dividing by 100. That way you’ll always represent the right number, even if it’s over 9000. :stuck_out_tongue_winking_eye: