-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake_latex_table.py
127 lines (106 loc) · 3.01 KB
/
make_latex_table.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
#!/usr/bin/env python
import sys
from collections import OrderedDict
from argparse import ArgumentParser
def argparser():
ap = ArgumentParser(description='make latex table from results in TSV')
ap.add_argument(
'--caption',
default='TODO: Caption',
help='table caption'
)
ap.add_argument(
'--label',
default='tab:todo-label',
help='table label'
)
ap.add_argument(
'--wide',
action='store_true',
help='use table*'
)
ap.add_argument(
'--decimals',
type=int,
default=1,
help='number of decimal places'
)
ap.add_argument(
'--percentage',
action='store_true',
help='format values as percentages'
)
ap.add_argument(
'--name-map',
metavar='NAME:LABEL,...',
help='map names to labels'
)
ap.add_argument(
'--order',
metavar='NAME,NAME,...',
help='name order'
)
ap.add_argument(
'data',
nargs='+',
metavar='NAME:FILE',
)
return ap
def load_tsv(fn):
data = OrderedDict()
with open(fn) as f:
for ln, l in enumerate(f, start=1):
label, value = l.split('\t')
assert label not in data
data[label] = float(value)
return data
def format_value(value, args):
if args.percentage:
return f'{value:.{args.decimals}%}'.replace('%', r'\%')
else:
return f'{value:.{args.decimals}}'
def main(argv):
args = argparser().parse_args(argv[1:])
if args.name_map:
name_map = dict(kv.split(':') for kv in args.name_map.split(','))
else:
name_map = {}
names, data = [], {}
for d in args.data:
name, fn = d.split(':')
name = name_map.get(name, name)
names.append(name)
assert name not in data, f'duplicate name {name}'
data[name] = load_tsv(fn)
# check that labels match
for n in names[1:]:
assert data[n].keys() == data[names[0]].keys()
labels = list(data[names[0]].keys())
# reorder if --order provided
if args.order:
assert set(names) == set(args.order.split(','))
names = args.order.split(',')
env_name = 'table' if not args.wide else 'table*'
TABLE_START = '''
% NOTE: this latex table is generated by the script
% https://github.com/LumiOpen/evals/blob/master/make_latex_table.py.
% To change the table, you should probably edit and rerun the script.
\\begin{'''+env_name+'''}[t!]
\\centering
\\begin{tabular}{l|'''+'l'*len(names)+'''}
'''.strip('\n')
print(TABLE_START)
print(' & '.join(['']+names) + r' \\ \hline')
for i in labels:
values = [format_value(data[n][i], args) for n in names]
label = i.replace('_', r'\_')
print(' & '.join([label]+values) + r' \\')
TABLE_END = '''
\\end{tabular}
\\caption{'''+args.caption+'''}
\\label{'''+args.label+'''}
\\end{'''+env_name+'''}
'''.strip('\n')
print(TABLE_END)
if __name__ == '__main__':
sys.exit(main(sys.argv))