-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplots.py
97 lines (72 loc) · 2.53 KB
/
plots.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
#!/usr/bin/env python3
import argparse
import csv
import sys
from contextlib import ExitStack
from typing import TextIO
from dateutil import parser as dup
import plotly.express as px
def load_data(file: TextIO) -> tuple[list[dict], str]:
'''
Loads data from a CSV file. It automatically detects the delimiter based on
the file content
'''
preview = file.readline(9)
file.seek(0)
if not preview.startswith('datetime'):
raise ValueError('Content must start with "datetime"')
delimiter = preview[8]
data = list(csv.DictReader(file, delimiter=delimiter))
for entry in data:
entry['datetime'] = dup.parse(entry['datetime'])
entry['amount'] = float(entry['amount'])
entry['total'] = float(entry['total'])
return data, delimiter
def main(argv=None):
if argv is None:
argv = sys.argv
parser = argparse.ArgumentParser(
description='Generate plots based on data computed with cashlog'
)
parser.add_argument('file_in', metavar='FILE_IN', type=str,
nargs='?', default='-',
help='Input file. If set to "-" then stdin is used '
'(default: -)')
parser.add_argument('-a', '--plot-amount', action='store_true',
help='Generate plot based on amount values')
parser.add_argument('-t', '--plot-total', action='store_true',
help='Generate plot based on total values')
args = parser.parse_args(argv[1:])
############################################################################
with ExitStack() as stack:
file_in = (sys.stdin if args.file_in == '-'
else stack.enter_context(open(args.file_in, 'r')))
data, _ = load_data(file_in)
if args.plot_amount:
fig = px.bar(
data,
y='amount',
template='plotly_dark',
title='Amount values',
color_discrete_sequence=['#fd0'],
hover_name='datetime',
hover_data=['desc'],
)
fig.show()
if args.plot_total:
fig = px.line(
data,
x='datetime',
y='total',
template='plotly_dark',
title='Total values',
line_shape='hv',
hover_name='datetime',
hover_data=['amount', 'desc'],
markers=True,
)
fig.update_traces(marker={'size': 8, 'color': '#fd0'})
fig.show()
return 0
if __name__ == '__main__':
sys.exit(main())