The dashboard user function
Source code in src/main.py
def dashboard(config: Config):
# internal parameters
# (possibly to generalise later)
config.expstart = 0
config.label_path_effects = {
"linewidth": 1,
"foreground": config.colors.contrast,
}
############# HELPERS
config.errors = {}
config.errors["DateColMissing"] = f"One column must be called '{config.strings.datecol}'."
config.dotstyle = {
"marker": config.marker,
"markersize": config.markersize,
"linestyle": "None",
}
config.projstyle = {
"linestyle": "-",
"marker": "None",
"linewidth": config.linewidth / 4,
}
config = read_headers(config)
############# DATA
alldata = pd.read_csv(config.csvdir + config.csv, header=1).fillna(0)
alldata.columns = list(config.hdrnew.keys())
alldata["Year"] = dates_to_years(config, alldata)
expend_count_cols = [col+"_count" for col in config.expend_cols]
alldata[expend_count_cols] = alldata[config.expend_cols].applymap(_expr_expend_count)
expend_price_cols = [col+"_price" for col in config.expend_cols]
alldata[expend_price_cols] = alldata[config.expend_cols].applymap(_expr_expend_price)
alldata[config.expend_cols] = alldata[config.expend_cols].applymap(_expr_expend)
alldata[config.cash_cols] = alldata[config.cash_cols].applymap(_expr)
alldata[config.income_cols] = alldata[config.income_cols].applymap(_expr)
config.retire_yr = config.born_yr + config.retire_age
ahead_yr = datetime.now(timezone.utc).year + config.future_window
config.max_yr = min(ahead_yr, config.retire_yr)
config.since_yr = config.since_yr or min(alldata.Year)
config.until_yr = config.until_yr or max(alldata.Year)
config.years_until_retire = config.max_yr - config.since_yr
config.age_at_retire = config.max_yr - config.born_yr
alldata["Days"] = dates_to_days(config, alldata)
alldata["totalSuper"] = alldata[config.super_cols].sum(axis=1)
alldata["totalShares"] = alldata[config.shares_cols].sum(axis=1)
alldata["totalCash"] = alldata[config.cash_cols].sum(axis=1)
alldata["totalExpend"] = alldata[config.expend_cols].sum(axis=1)
alldata["totalIncome"] = alldata[config.income_cols].sum(axis=1)
alldata["total"] = alldata["totalShares"] + alldata["totalSuper"] + alldata["totalCash"]
alldata = alldata.sort_values(by="Days").reset_index(drop=True)
income_grand_tot = alldata["totalIncome"].sum()
income_sum = alldata[config.income_cols].sum()
config.income_minor = list(income_sum[income_sum < (1 - config.income_thresh) * income_grand_tot].keys())
config.iminor_bool = len(config.income_minor) > 0
## not currently used in the cash panel but this should be generalised
# cash_grand_tot = alldata["totalCash"].sum()
# cash_sum = alldata[config.cash_cols].sum()
# config.cash_minor = list(cash_sum[cash_sum < (1 - config.cash_thresh) * cash_grand_tot].keys())
# config.cminor_bool = len(config.cash_minor) > 0
config.years_uniq = {}
for x in alldata["Year"]:
if x >= config.since_yr and x <= config.until_yr:
config.years_uniq[x] = True
########### CREATE FIGURE and AXES
if isinstance(config.layout, str):
config.layout = [config.layout]
if "main7" in config.layout:
create_dashboard_main7(config, alldata)
if "plain8" in config.layout:
create_dashboard_plain8(config, alldata)
if "income4" in config.layout:
create_dashboard_income4(config, alldata)
if "cash4" in config.layout:
create_dashboard_cash4(config, alldata)
if "share4" in config.layout:
create_dashboard_share4(config, alldata)
if "ipad_1" in config.layout:
create_dashboard_ipad1(config, alldata)
The Config class
Configuration class for networthdash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout
|
str
|
Names visual layout style. Accepts one or more of: {"main7","plain8"} |
'main7'
|
csv
|
str
|
Filename of the CSV input file. Path information should not be included. |
'net-worth.csv'
|
csvdir
|
str
|
Path to the CSV input file. Concatenated directly with the CSV filename, so should end in a "/". |
'./'
|
savedir
|
str
|
Path (ending in "/") to save PDF dashboards. |
'Net worth archive/'
|
saveprefix
|
str
|
First part of filename to save. Defaults to the CSV filename stripped of its file extension. |
None
|
savesuffix
|
str
|
Second part of the filename is a date stamp specified in standard datetime format (e.g., |
'%Y-%m'
|
savepdf
|
bool
|
If true saves a PDF of the dashboard in the |
True
|
savejpg
|
bool
|
If true saves a JPG of the dashboard in the |
False
|
savepng
|
bool
|
If true saves a PNG of the dashboard in the |
False
|
datefmt
|
str
|
The date format used in the CSV file. |
'%Y/%m/%d'
|
since_yr
|
int
|
Year to start the dashboard (default is the earliest year in the CSV file). |
None
|
until_yr
|
int
|
Year to conclude the dashboard (default is the latest year in the CSV file). |
None
|
born_yr
|
int
|
The year you were born. |
required |
retire_age
|
int
|
The age at which you expect to retire. |
67
|
retire_ratio
|
float
|
Thw fraction of your net worth to commence drawing down from yearly in retirement (e.g., for the "4% rule" it would be 0.04). |
0.04
|
cash_thresh
|
float
|
Threshold (between 0 and 1) for identifying "major" or "minor" cash sources based on the all-time grand totals for each cash column. |
required |
income_thresh
|
float
|
Threshold (between 0 and 1) for identifying "major" or "minor" income sources based on the all-time grand totals for each income column. |
0.6
|
linear_window
|
float
|
Number of years before the current date to linearly extrapolate from. |
1.0
|
future_window
|
float
|
The maximum number of extrapolation years to show on the graph. |
8
|
linear_targets
|
list[float]
|
"Targets" to extrapolate to linearly to gauge time until net worth milestones. |
(5000, 10000, 15000, 20000, 35000, 50000, 75000, 100000, 150000, 200000, 350000, 500000, 750000, 1000000, 1500000, 2000000, 3500000, 5000000, 7500000, 10000000, 20000000, 50000000, 100000000)
|
anon
|
bool
|
If True, hides all numerical labels. |
False
|
colors
|
Colors
|
Colors class setup for plot colours. See Colors class for defaults and options. |
Colors()
|
strings
|
Strings
|
Strings class setup for dashboard strings. Includes strings used in the CSV file. See Strings class for defaults and options. |
Strings()
|
figw
|
float
|
Plot size, horizontal width (physical size). |
6
|
figh
|
float
|
Plot size, vertical height (physical size). |
12.5
|
linewidth
|
float
|
Linewidth of scatter plots. |
1.0
|
marker
|
str
|
Marker of scatter plots. |
'.'
|
markersize
|
float
|
Markersize of scatter plots. |
4.0
|
node_width
|
float
|
Relative width of Sankey diagram nodes (ausankey parameter). |
0.15
|
node_alpha
|
float
|
Alpha (transparency) of Sankey diagram nodes (ausankey parameter). |
0.8
|
flow_alpha
|
float
|
Alpha (transparency) of Sankey diagram flow transitions between nodes (ausankey parameter). |
0.5
|
currency_sign
|
str
|
The currency sign used to display amounts. |
required |
sankey_sort
|
str
|
The sort option to pass through to the Sankey diagrams. Valid options are |
'bottom'
|
sankey_colormaps
|
list
|
Three colormaps for the panels which are automatically coloured based on breakdown of components. (I.e., not coloured using the Colors class.) |
('Set3', 'Pastel1', 'Pastel2')
|
Source code in src/config.py
@dataclass
class Config:
"""
Configuration class for networthdash.
Parameters
----------
layout : str
Names visual layout style. Accepts one or more of:
{"main7","plain8"}
csv : str
Filename of the CSV input file. Path information should not be included.
csvdir : str
Path to the CSV input file. Concatenated directly with the CSV filename, so should end in a "/".
savedir : str
Path (ending in "/") to save PDF dashboards.
saveprefix : str
First part of filename to save. Defaults to the CSV filename stripped of its file extension.
savesuffix : str
Second part of the filename is a date stamp specified in standard datetime format (e.g., `%Y-%m-%d`). Default setting omits the day, assuming you don't need to log updates too often.
savepdf : bool
If true saves a PDF of the dashboard in the `savedir` folder.
savejpg : bool
If true saves a JPG of the dashboard in the `savedir` folder.
savepng : bool
If true saves a PNG of the dashboard in the `savedir` folder.
datefmt : str
The date format used in the CSV file.
since_yr : int
Year to start the dashboard (default is the earliest year in the CSV file).
until_yr : int
Year to conclude the dashboard (default is the latest year in the CSV file).
born_yr : int
The year you were born.
retire_age : int
The age at which you expect to retire.
retire_ratio : float
Thw fraction of your net worth to commence drawing down from yearly in retirement (e.g., for the "4% rule" it would be 0.04).
cash_thresh : float
Threshold (between 0 and 1) for identifying "major" or "minor" cash sources based on the all-time grand totals for each cash column.
income_thresh : float
Threshold (between 0 and 1) for identifying "major" or "minor" income sources based on the all-time grand totals for each income column.
linear_window : float
Number of years before the current date to linearly extrapolate from.
future_window : float
The maximum number of extrapolation years to show on the graph.
linear_targets: list[float]
"Targets" to extrapolate to linearly to gauge time until net worth milestones.
anon : bool
If True, hides all numerical labels.
colors : Colors
Colors class setup for plot colours. See Colors class for defaults and options.
strings : Strings
Strings class setup for dashboard strings. Includes strings used in the CSV file. See Strings class for defaults and options.
figw : float
Plot size, horizontal width (physical size).
figh : float
Plot size, vertical height (physical size).
linewidth : float
Linewidth of scatter plots.
marker : str
Marker of scatter plots.
markersize : float
Markersize of scatter plots.
node_width : float
Relative width of Sankey diagram nodes (ausankey parameter).
node_alpha : float
Alpha (transparency) of Sankey diagram nodes (ausankey parameter).
flow_alpha : float
Alpha (transparency) of Sankey diagram flow transitions between nodes (ausankey parameter).
currency_sign : str
The currency sign used to display amounts.
sankey_sort : str
The sort option to pass through to the Sankey diagrams. Valid options are `"top"`, `"bottom"`, `"none"`.
sankey_colormaps : list
Three colormaps for the panels which are automatically coloured based on breakdown of components. (I.e., not coloured using the Colors class.)
"""
born_yr: int
layout: str = "main7"
csv: str = "net-worth.csv"
csvdir: str = "./"
datefmt: str = "%Y/%m/%d"
savedir: str = "Net worth archive/"
saveprefix: str = None
savesuffix: str = "%Y-%m"
savepdf: bool = True
savejpg: bool = False
savepng: bool = False
since_yr: int = None
until_yr: int = None
retire_age: int = 67
retire_ratio: float = 0.04
# cash_thresh: float = 0.6
income_thresh: float = 0.6
linear_window: float = 1.0
future_window: int = 8
anon: bool = False
figw: float = 6
figh: float = 12.5
linewidth: float = 1.0
markersize: float = 4.0
marker: str = "."
colors: "Colors" = field(default_factory=Colors)
strings: "Strings" = field(default_factory=Strings)
node_width: float = 0.15
node_alpha: float = 0.8
flow_alpha: float = 0.5
currencysign = "$"
sankey_sort: str = "bottom"
sankey_colormaps: list = ("Set3", "Pastel1", "Pastel2")
linear_targets: list[float] = (
5000,
10000,
15000,
20000,
35000,
50000,
75000,
100000,
150000,
200000,
350000,
500000,
750000,
1000000,
1500000,
2000000,
3500000,
5000000,
7500000,
10000000,
20000000,
50000000,
100000000,
)
The Colors class
Color class for networthdash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bg
|
str
|
Background colour of the figure. |
'#272727'
|
axis
|
str
|
Background colour of the axes. |
'#4e4e4e'
|
text
|
str
|
Colour of generic text. |
'white'
|
contrast
|
str
|
Colour of contrast text (e.g., overlaid percentages on Sankey plots). |
'black'
|
label
|
str
|
Colour of text labels. |
'white'
|
title
|
str
|
Colour of axis titles. |
'white'
|
tick
|
str
|
Colour of axis ticks. |
'white'
|
dashes
|
str
|
Colour of dashed lines. |
'white'
|
frame
|
str
|
Colour of axis frames. |
'white'
|
grid
|
str
|
Colour of axis grids. |
'#b5b5b5'
|
target
|
str
|
Colour of extrapolated target intersection lines. |
'#b5b5b5'
|
super
|
str
|
Colour of Super lines/labels. |
'#ffbf80'
|
total
|
str
|
Colour of total net worth lines/labels. |
'#8ec6ff'
|
shares
|
str
|
Colour of Shares lines/labels. |
'#5eff86'
|
cash
|
str
|
Colour of Cash lines/labels. |
'#ffa1a1'
|
expend
|
str
|
Colour of lines/labels for expenditure on shares investments. |
'#e9a8ff'
|
Source code in src/colors.py
@dataclass
class Colors:
"""
Color class for networthdash.
Parameters
----------
bg : str
Background colour of the figure.
axis : str
Background colour of the axes.
text : str
Colour of generic text.
contrast : str
Colour of contrast text (e.g., overlaid percentages on Sankey plots).
label : str
Colour of text labels.
title : str
Colour of axis titles.
tick : str
Colour of axis ticks.
dashes : str
Colour of dashed lines.
frame : str
Colour of axis frames.
grid : str
Colour of axis grids.
target : str
Colour of extrapolated target intersection lines.
super : str
Colour of Super lines/labels.
total : str
Colour of total net worth lines/labels.
shares : str
Colour of Shares lines/labels.
cash : str
Colour of Cash lines/labels.
expend : str
Colour of lines/labels for expenditure on shares investments.
"""
bg: str = "#272727"
axis: str = "#4e4e4e"
text: str = "white"
contrast: str = "black"
label: str = "white"
title: str = "white"
tick: str = "white"
dashes: str = "white"
frame: str = "white"
grid: str = "#b5b5b5"
target: str = "#b5b5b5"
super: str = "#ffbf80"
total: str = "#8ec6ff"
shares: str = "#5eff86"
cash: str = "#ffa1a1"
expend: str = "#e9a8ff"
income: str = "#e3a3aa"
def __getitem__(self, key: str) -> str:
return getattr(self, key)