Py.Cafe

Angella062022/

dash-microfinance-sales-analysis

Microfinance Sales Analysis with Dash

DocsPricing
  • app.py
  • dashdebug.py
  • requirements.txt
dashdebug.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import dash
from dash import Input, Output, html, dcc
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
import numpy as np

# Sample sales dataset
data = {
    'Transaction_ID': range(1, 101),
    'Date': pd.date_range(start='2023-01-01', periods=100, freq='D'),
    'Product_Category': ['Loan', 'Savings', 'Insurance'] * 33 + ['Loan'],
    'Region': ['North', 'South', 'East', 'West'] * 25,
    'Sale_Amount': [round(abs(x), 2) for x in pd.Series(np.random.randn(100) * 1000 + 5000)]
}

df = pd.DataFrame(data)

# Initialize Dash app
app = dash.Dash(__name__)

# Custom CSS style (moved here from html.Style)
card_style = {
    'border': '1px solid #ddd',
    'borderRadius': '10px',
    'padding': '20px',
    'margin': '10px',
    'textAlign': 'center',
    'boxShadow': '2px 2px 12px #aaa',
    'flex': '1'
}

# App layout
app.layout = html.Div([
    html.H1("Microfinance Sales Dashboard", style={'textAlign': 'center', 'color': 'blue'}),

    # Filters
    html.Div([
        html.Div([
            html.Label("Select Region:"),
            dcc.Dropdown(
                id='region-filter',
                options=[{'label': region, 'value': region} for region in df['Region'].unique()],
                multi=True,
                value=df['Region'].unique().tolist()
            ),
        ], style={'flex': '1'}),

        html.Div([
            html.Label("Select Product Category:"),
            dcc.Dropdown(
                id='category-filter',
                options=[{'label': category, 'value': category} for category in df['Product_Category'].unique()],
                multi=True,
                value=df['Product_Category'].unique().tolist()
            ),
        ], style={'flex': '1'}),

        html.Div([
            html.Label("Select Date Range:"),
            dcc.DatePickerRange(
                id='date-filter',
                start_date=df['Date'].min(),
                end_date=df['Date'].max(),
                display_format='YYYY-MM-DD'
            ),
        ], style={'flex': '1'}),
    ], style={'display': 'flex', 'gap': '20px', 'margin': '20px'}),

    # Metrics Cards
    html.Div([
        html.Div([
            html.H3("Total Sales"),
            html.P(id='total-sales')
        ], style=card_style),

        html.Div([
            html.H3("Average Sale Amount"),
            html.P(id='avg-sales')
        ], style=card_style),

        html.Div([
            html.H3("Total Transactions"),
            html.P(id='transaction-count')
        ], style=card_style),
    ], style={'display': 'flex', 'justifyContent': 'space-around'}),

    # Visualizations with full-screen support
    html.Div([
        dcc.Graph(id='sales-trend', config={'displayModeBar': True, 'displaylogo': False}),
        dcc.Graph(id='sales-category', config={'displayModeBar': True, 'displaylogo': False}),
        dcc.Graph(id='sales-region', config={'displayModeBar': True, 'displaylogo': False}),
    ]),
])

# Callback to update charts and metrics
@app.callback(
    [Output('sales-trend', 'figure'),
     Output('sales-category', 'figure'),
     Output('sales-region', 'figure'),
     Output('total-sales', 'children'),
     Output('avg-sales', 'children'),
     Output('transaction-count', 'children')],
    [Input('region-filter', 'value'),
     Input('category-filter', 'value'),
     Input('date-filter', 'start_date'),
     Input('date-filter', 'end_date')]
)
def update_dashboard(selected_regions, selected_categories, start_date, end_date):
    # Filter data
    filtered_df = df[
        (df['Region'].isin(selected_regions)) &
        (df['Product_Category'].isin(selected_categories)) &
        (df['Date'] >= pd.to_datetime(start_date)) &
        (df['Date'] <= pd.to_datetime(end_date))
    ]

    # Metrics
    total_sales = filtered_df['Sale_Amount'].sum()
    avg_sales = filtered_df['Sale_Amount'].mean()
    transaction_count = filtered_df.shape[0]

    # Sales trend over time
    fig_trend = px.line(filtered_df, x='Date', y='Sale_Amount', title='Sales Trend Over Time')

    # Sales by product category
    fig_category = px.bar(filtered_df, x='Product_Category', y='Sale_Amount', title='Sales by Product Category',
                          color='Product_Category')

    # Sales by region (pie chart)
    fig_region = px.pie(filtered_df, names='Region', values='Sale_Amount', title='Sales by Region')

    # Metric card content
    total_sales_text = f"${total_sales:,.2f}"
    avg_sales_text = f"${avg_sales:,.2f}" if transaction_count > 0 else "$0.00"
    transaction_count_text = f"{transaction_count}"

    return fig_trend, fig_category, fig_region, total_sales_text, avg_sales_text, transaction_count_text


# Run app
if __name__ == '__main__':
    app.run_server(debug=False)