Add detailed balance plot

This commit is contained in:
Andreas Tsouchlos 2024-01-02 01:23:00 +01:00
parent dd9e44eace
commit c745d23ab8
5 changed files with 104 additions and 45 deletions

View File

@ -1,48 +1,9 @@
from banking_breakdown import document_builder
import pandas as pd
from banking_breakdown import types
import numpy as np
def _generate_dummy_data() -> types.ReportData:
categories = ["A", "B", "C", "D", "E", "F", "G"]
values = np.array([10, 12, 53, 12, 90, 23, 32])
values = values / values.sum() * 100
values = np.round(values, decimals=1)
values[-1] += 100 - np.sum(values)
category_overview_df = pd.DataFrame(
{"category": categories, "value": values})
t = ["2023-01-01",
"2023-02-01",
"2023-03-01",
"2023-04-01",
"2023-05-01",
"2023-06-01",
"2023-07-01",
"2023-08-01",
"2023-09-01",
"2023-10-01",
"2023-11-01",
"2023-12-01"]
net_income = 200 * np.random.normal(size=len(t)) + 100
net_income_df = pd.DataFrame({"t": t, "value": net_income})
total_value = np.cumsum(net_income)
total_value_df = pd.DataFrame({"t": t, "value": total_value})
report_data = types.ReportData(category_overview=category_overview_df,
net_income=net_income_df,
total_value=total_value_df)
return report_data
from banking_breakdown import statement_parser
def main():
report_data = _generate_dummy_data()
report_data = statement_parser.parse_statement("res/banking_statement_2023.csv")
document_builder.build_document(report_data)

View File

@ -15,6 +15,8 @@ def _serialize_report_data(report_data: types.ReportData):
report_data.category_overview.to_csv('build/category_overview.csv',
index=False)
report_data.total_value.to_csv('build/total_value.csv', index=False)
report_data.detailed_balance.to_csv('build/detailed_balance.csv',
index=False)
def _compile_document():

View File

@ -0,0 +1,80 @@
import typing
import pandas as pd
from banking_breakdown import types
import json
import re
import numpy as np
def _read_regex_dict(regex_file: str = "res/category_regexes.json"):
with open(regex_file, 'r') as f:
return json.load(f)
def _tag_with_category(df: pd.DataFrame) -> pd.DataFrame:
regex_dict = _read_regex_dict()
return df
def _compute_total_balance(df: pd.DataFrame) -> pd.DataFrame:
stripped_df = pd.DataFrame(
{'t': df["Buchungstag"], 'value': df["Saldo nach Buchung"]})
stripped_df.index = stripped_df['t']
gb = stripped_df.groupby(pd.Grouper(freq='M'))
result = gb.tail(1)['value'].reset_index()
#result['t'] = result['t'].apply(lambda dt: dt.replace(day=1))
return result
def _compute_net_income(df: pd.DataFrame) -> pd.DataFrame:
stripped_df = pd.DataFrame({'t': df["Buchungstag"], 'value': df["Betrag"]})
result = stripped_df.resample(rule='M', on="t").sum().reset_index()
#result['t'] = result['t'].apply(lambda dt: dt.replace(day=1))
return result
def _compute_category_overview(df: pd.DataFrame) -> pd.DataFrame:
categories = ["A", "B", "C", "D", "E", "F", "G"]
values = np.array([10, 12, 53, 12, 90, 23, 32])
values = values / values.sum() * 100
values = np.round(values, decimals=1)
values[-1] += 100 - np.sum(values)
category_overview_df = pd.DataFrame(
{"category": categories, "value": values})
return category_overview_df
def _compute_detailed_balance(df: pd.DataFrame) -> pd.DataFrame:
return pd.DataFrame({'t': df["Buchungstag"],
'value': df["Saldo nach Buchung"]})
def parse_statement(filename: str) -> types.ReportData:
df = pd.read_csv(filename, delimiter=';', decimal=",")
df["Buchungstag"] = pd.to_datetime(df["Buchungstag"], format='%d.%m.%Y')
category_overview_df = _compute_category_overview(df)
total_balance_df = _compute_total_balance(df)
net_income_df = _compute_net_income(df)
detailed_balance_df = _compute_detailed_balance(df)
return types.ReportData(category_overview_df,
net_income_df,
total_balance_df,
detailed_balance_df)
def main():
report_data = parse_statement("../res/banking_statement_2023.csv")
if __name__ == "__main__":
main()

View File

@ -7,3 +7,4 @@ class ReportData:
category_overview: pd.DataFrame
net_income: pd.DataFrame
total_value: pd.DataFrame
detailed_balance: pd.DataFrame

View File

@ -153,12 +153,18 @@
anchor=near xticklabel,
},
grid,
enlarge x limits=0.03,
]
% Dummy plot to set x axis labels
% Dummy plot to set x axis ticks
\addplot[draw=none]
table[col sep=comma, x=t, y=value]
{net_income.csv};
% Dummy plot to set x axis scale
\addplot[draw=none]
table[col sep=comma, x=t, y=value]
{detailed_balance.csv};
\addplot[ybar, color=scol2, fill=scol2, line width=1pt]
table[col sep=comma, x=t, y=value, discard if lt={value}{0}]
{net_income.csv};
@ -176,20 +182,28 @@
date coordinates in=x,
width=\textwidth,
height=0.375\textwidth,
area style,
ylabel={Total balance in €},
y label style={at={(-0.1,0.5)},anchor=south},
xticklabel=\month.\shortyear{\year},
xtick=data,
enlarge x limits=0.03,
xticklabel style={
rotate=60,
anchor=near xticklabel,
},
grid,
]
\addplot+[mark=none, color=scol1, line width=1pt]
% Dummy plot to set x axis ticks
\addplot[draw=none]
table[col sep=comma, x=t, y=value]
{total_value.csv} \closedcycle;
{total_value.csv};
\addplot[scol3, mark=none, line width=1pt]
table[col sep=comma, x=t, y=value]
{detailed_balance.csv};
\addplot[scol1, mark=none, line width=1pt]
table[col sep=comma, x=t, y=value]
{total_value.csv};
\end{axis}
\end{tikzpicture}
\end{subfigure}
@ -197,5 +211,6 @@
\caption{Development of account balance over time}
\end{figure}
\end{document}