-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwisetable.py
151 lines (119 loc) · 6.51 KB
/
wisetable.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
from functools import partial
import numpy as np
import param
import pandas as pd
import panel as pn
from experimentdata import ExperimentData
from problemtable import ProblemTablereport
from report import Report
class WiseTablereport(Report):
attribute = param.Selector(default="--")
def __init__(self, experiment_data = ExperimentData(), param_dict = dict(), **params):
super().__init__(experiment_data, **params)
self.domain_wise_table = pd.DataFrame()
self.task_wise_table = pd.DataFrame()
self.per_task_table = pd.DataFrame()
self.per_domain_table = pd.DataFrame()
self.domain_wise = pn.widgets.Tabulator(pd.DataFrame(), disabled = True, sortable=False, pagination="remote", page_size=1000)
self.domain_wise.style.apply(func=partial(self.style_wise_by_row, table_type="domain"), axis=1)
self.domain_wise.on_click(self.on_domain_wise_click_callback)
self.task_wise = pn.widgets.Tabulator(pd.DataFrame(), disabled = True, sortable=False, pagination="remote", page_size=1000)
self.task_wise.style.apply(func=partial(self.style_wise_by_row, table_type="task"), axis=1)
self.task_wise.on_click(self.on_task_wise_click_callback)
self.data_view = pn.Column(
pn.pane.HTML("Domain Wise", styles={'font-size': '12pt', 'font-family': 'Arial', 'font-weight': 'bold', 'padding-left': '10px'}),
self.domain_wise,
pn.pane.HTML("Task Wise", styles={'font-size': '12pt', 'font-family': 'Arial', 'font-weight': 'bold', 'padding-left': '10px'}),
self.task_wise,
)
self.param_view = pn.Column(
pn.Param(self.param.attribute),
pn.pane.Markdown("""
### Information
Shows on how many domains/problems the row entry algorithm is
better than the column entry algorithm. Clicking on a cell
gives a detailed comparison table below the domain/task wise
tables.
When having a taskwise comparison open, klicking on a row will
open a ProblemReport comparing all attributes for this specific
problem.
""")
)
param_dict = self.set_experiment_data_dependent_parameters() | param_dict
self.param.update(param_dict)
def set_experiment_data_dependent_parameters(self):
param_updates = super().set_experiment_data_dependent_parameters()
self.param.attribute.objects = ["--"] + self.experiment_data.numeric_attributes
param_updates["attribute"] = self.param.attribute.objects[0]
d = { a1 : {a2 : 0 for a2 in self.experiment_data.algorithms} for a1 in self.experiment_data.algorithms }
self.task_wise_table = pd.DataFrame(d)
self.domain_wise_table = pd.DataFrame(d)
return param_updates
def style_wise_by_row(self, row, table_type):
style = [""] * len(row)
row_alg = row.name
df = self.task_wise_table if table_type == "task" else self.domain_wise_table
for i, (alg, val) in enumerate(row.items()):
if df.at[alg, row_alg] < val:
style[i] = style[i] + "font-weight:bold;"
elif row.name == alg:
style[i] = style[i] + "color:gray;"
return style
def on_domain_wise_click_callback(self, e):
self.domain_wise.selection = []
row_alg = self.domain_wise_table.iloc[e.row].name
col_alg = e.column
if col_alg not in self.domain_wise_table.columns:
return
comparison = pn.widgets.Tabulator(
self.per_domain_table[[(row_alg, col_alg, "win")]].copy(),
disabled = True, pagination="remote", page_size=100)
self.add_popup(comparison, name=f"Domain comparison {row_alg} vs {col_alg}")
def on_task_wise_click_callback(self, e):
self.task_wise.selection = []
row_alg = self.task_wise_table.iloc[e.row].name
col_alg = e.column
if col_alg not in self.task_wise_table.columns:
return
comparison = pn.widgets.Tabulator(
self.per_task_table[list({row_alg, col_alg, (row_alg, col_alg)})].copy(),
disabled = True, pagination="remote", page_size=100)
comparison.on_click(partial(self.on_comparison_click_callback, df=comparison.value))
self.add_popup(comparison, name=f"Task comparison {row_alg} vs {col_alg}")
def on_comparison_click_callback(self, e, df):
row = df.iloc[e.row]
dom = row.name[0]
prob = row.name[1]
param_dict = {
"domain": dom,
"problem": prob,
"algorithms": list(set(row.keys()).intersection(set(self.experiment_data.algorithms)))
}
problem_report = ProblemTablereport(self.experiment_data, param_dict,
sizing_mode = "stretch_width")
self.add_popup(problem_report.view_data, name=f"{dom} - {prob}")
def update_data_view(self):
if not self.attribute or self.attribute == "--":
self.data_view.value = pd.DataFrame()
return
min_wins = self.experiment_data.attribute_info[self.attribute].min_wins
self.per_task_table = self.experiment_data.data.loc[self.attribute].copy()
self.per_task_table.replace([np.NaN, None], np.inf if min_wins else -np.inf, inplace=True)
for a1 in self.experiment_data.algorithms:
l = []
for a2 in self.experiment_data.algorithms:
self.per_task_table[(a1,a2)] = self.per_task_table[a1]-self.per_task_table[a2]
self.per_task_table[(a1,a2,"win")] = np.sign(self.per_task_table[(a1,a2)])
if min_wins:
self.per_task_table[(a1,a2,"win")] *= -1
num_better = len(self.per_task_table[(self.per_task_table[(a1,a2,"win")] > 0)].index)
self.task_wise_table.at[a1,a2] = num_better
self.per_domain_table[(a1,a2,"win")] = self.per_task_table[(a1,a2,"win")].groupby(["domain"]).sum()
self.domain_wise_table.at[a1,a2] = len(self.per_domain_table[self.per_domain_table[(a1,a2,"win")] > 0].index)
self.task_wise.value = self.task_wise_table[self.experiment_data.algorithms]
self.domain_wise.value = self.domain_wise_table[self.experiment_data.algorithms]
def get_params_as_dict(self):
return super().get_params_as_dict()
# we set domain and problem sepearately because domain prepares the problem attribute with the possible values
def set_params_from_dict(self, params):
self.attribute = params["attribute"]