Py.Cafe

acabrera.citizens/

us_federal_expenditures

us_federal_expenditures

DocsPricing
  • all_outlays_2025-02-14.csv
  • app.py
  • requirements.txt
  • us_federal_expenditures.py
app.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
145
146
147
148
149
150
151
152
import numpy as np
import pandas as pd
import plotly.express as px
import dash
import dash_bootstrap_components as dbc
from dash import Dash, html,  dcc, Input, Output, State

df = pd.read_csv("all_outlays_2025-02-14.csv", parse_dates=['Date'])

df['pct_change'] = df['Daily'].pct_change()
df['pct_change'] = df['pct_change'].replace([np.inf, -np.inf], np.nan)
df['pct_change'] = df['pct_change'].fillna(0)

pivot_df = (
    df.pivot_table(
        index=["Date"],
        columns="transaction_catg_renamed",
        values="Daily",
        aggfunc="sum"
    )
    .fillna(0)
)

pivot_pct_df = (
    df.pivot_table(
        index=["Date"],
        columns="transaction_catg_renamed",
        values="pct_change",
    )
    .fillna(0)
)

categories = df['transaction_catg_renamed'].unique()

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.UNITED])

app.title = "US federal government’s expenditure"

sidebar = dbc.Col([
    html.Hr(),
    html.H6("Selecting Time Frequency"),
    dbc.RadioItems(
        id="period-filter",
        options=[
            {'label': 'Days', 'value': 'D'},
            {'label': 'Weeks', 'value': 'W'},
            {'label': 'Months', 'value': 'ME'},
            {'label': 'Quarters', 'value': 'QE'}
        ],
        value='ME',
        inline=False, 
        class_name="btn btn-info",
    ),
    html.Hr(),
    html.H6("Transaction Categories"),
    html.Hr(),
    dbc.Button("Select Categories", id="open-modal", n_clicks=0, className="btn btn-info"),
    dbc.Modal([
        dbc.ModalHeader("Select Categories"),
        dbc.ModalBody(dbc.Checklist(
            id='category-checklist',
            options=[{'label': cat, 'value': cat} for cat in categories],
            value=  ['IAP - USAID',
                     'Dept of Education (ED)', 
                     'Dept of Commerce (DOC)', 
                     'Dept of Energy (DOE)', 
                     'Dept of Justice (DOJ)'],
            inline=False,  
            switch=True,
            style={"backgroundColor": "#f0f0f0", "padding": "8px", "fontSize": "16px"}
        )),
        dbc.ModalFooter(
            dbc.Button("Close", id="close-modal", className="btn btn-info"
                      )
        )
    ], id="modal", is_open=False),
    html.Div(id="selected-categories", style={"marginTop": "10px"})
  
], width=3, style={'background-color': '#f8f9fa', 'padding': '20px', 'text-align': 'center', 'position': 'fixed',
    'height': '100vh',
    'overflow': 'auto'}) 


content = dbc.Col([
    html.H4("The Hamilton Project: Tracking US federal expenditure since 2022",
            style={"text-align": "center"}),
    html.Hr(),
    dbc.Row([
        html.H5("Total US Federal Spending Trends by Category",
                style={"backgroundColor": "#f0f0f0", "padding": "8px", "text-align": "center"}),
        dbc.Col(dcc.Graph(id="area-chart"), width=12),
    ]),
    dbc.Row([
        html.H5("Percentage Change in US Federal Expenditure by Category",
                style={"backgroundColor": "#f0f0f0", "padding": "8px", "text-align": "center"}),
        dbc.Col(dcc.Graph(id="line-chart"), width=12),
    ]),
], width={"size": 9, "offset": 3})

app.layout = dbc.Container([
    dbc.Row([
        sidebar,
        content
    ])
], fluid=True)

@app.callback(
    Output("modal", "is_open"),
    [Input("open-modal", "n_clicks"), Input("close-modal", "n_clicks")],
    [State("modal", "is_open")],
)
def toggle_modal(n1, n2, is_open):
    if n1 or n2:
        return not is_open
    return is_open

@app.callback(
    Output("selected-categories", "children"),
    Input('category-checklist', 'value')
)
def display_selected_categories(selected_categories):
    return f"Selected Categories: {', '.join(selected_categories)}" if selected_categories else "No categories selected"

@app.callback(
    Output("area-chart", "figure"),
    Output("line-chart", "figure"),
    Input("period-filter", "value"),
    Input('category-checklist', 'value')
)
def update_charts(selected_period, selected_categories):

    resample_str = selected_period

    filtered_pivot_df = pivot_df[selected_categories]
    filtered_pivot_pct_df = pivot_pct_df[selected_categories]

    resampled_pivot_df = filtered_pivot_df.resample(resample_str).sum()
    resampled_pivot_pct_df = filtered_pivot_pct_df.resample(resample_str).mean()

    fig_area = px.area(resampled_pivot_df, template='presentation', color_discrete_sequence=px.colors.qualitative.Prism,
                       labels={'transaction_catg_renamed': 'Transaction Categories', 'Date': '', 'value': 'US$ in Billions'},
                       markers=True)
    fig_area.update_layout(legend=dict(title=None, orientation="h", y=1, yanchor="bottom", x=0.5, xanchor="center",
                                        font=dict(size=16)))

    fig_line = px.line(resampled_pivot_pct_df, template='presentation', color_discrete_sequence=px.colors.qualitative.Prism,
                        labels={'transaction_catg_renamed': 'Transaction Categories', 'Date': '', 'value': 'Percentage Change %'},
                        markers=True)
    fig_line.update_layout(showlegend=False)

    return fig_area, fig_line