1
|
|
|
# Author: Simon Blanke |
2
|
|
|
# Email: [email protected] |
3
|
|
|
# License: MIT License |
4
|
|
|
|
5
|
|
|
import numbers |
6
|
|
|
import numpy as np |
7
|
|
|
import pandas as pd |
8
|
|
|
import matplotlib.pyplot as plt |
9
|
|
|
import plotly.express as px |
10
|
|
|
|
11
|
|
|
try: |
12
|
|
|
from progress_io import ProgressIO |
13
|
|
|
except: |
14
|
|
|
from .progress_io import ProgressIO |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
pd.options.mode.chained_assignment = "raise" |
18
|
|
|
|
19
|
|
|
|
20
|
|
|
color_scale = px.colors.sequential.Jet |
21
|
|
|
|
22
|
|
|
|
23
|
|
|
class StreamlitBackend: |
24
|
|
|
def __init__(self, search_ids): |
25
|
|
|
self.search_ids = search_ids |
26
|
|
|
self.search_id_dict = {} |
27
|
|
|
|
28
|
|
|
_io_ = ProgressIO("./") |
29
|
|
|
|
30
|
|
|
for search_id in search_ids: |
31
|
|
|
self.search_id_dict[search_id] = {} |
32
|
|
|
|
33
|
|
|
self.search_id_dict[search_id]["prog_d"] = _io_.load_progress(search_id) |
34
|
|
|
self.search_id_dict[search_id]["filt_f"] = _io_.load_filter(search_id) |
35
|
|
|
|
36
|
|
|
def get_progress_data(self, search_id): |
37
|
|
|
progress_data = self.search_id_dict[search_id]["prog_d"] |
38
|
|
|
|
39
|
|
|
if progress_data is None: |
40
|
|
|
return |
41
|
|
|
|
42
|
|
|
return progress_data[~progress_data.isin([np.nan, np.inf, -np.inf]).any(1)] |
43
|
|
|
|
44
|
|
|
def pyplot(self, progress_data): |
45
|
|
|
if progress_data is None or len(progress_data) <= 1: |
46
|
|
|
return None |
47
|
|
|
|
48
|
|
|
nth_iter = progress_data["nth_iter"] |
49
|
|
|
score_best = progress_data["score_best"] |
50
|
|
|
nth_process = list(progress_data["nth_process"]) |
51
|
|
|
|
52
|
|
|
if np.all(nth_process == nth_process[0]): |
53
|
|
|
fig, ax = plt.subplots() |
54
|
|
|
plt.plot(nth_iter, score_best) |
55
|
|
|
else: |
56
|
|
|
fig, ax = plt.subplots() |
57
|
|
|
ax.set_xlabel("nth iteration") |
58
|
|
|
ax.set_ylabel("best score") |
59
|
|
|
|
60
|
|
|
for i in np.unique(nth_process): |
61
|
|
|
nth_iter_p = nth_iter[nth_process == i] |
62
|
|
|
score_best_p = score_best[nth_process == i] |
63
|
|
|
plt.plot(nth_iter_p, score_best_p, label=str(i) + ". process") |
64
|
|
|
plt.legend() |
65
|
|
|
|
66
|
|
|
return fig |
67
|
|
|
|
68
|
|
|
def filter_data(self, df, filter_df): |
69
|
|
|
prog_data_columns = list(df.columns) |
70
|
|
|
|
71
|
|
|
if len(df) > 1: |
72
|
|
|
for column in prog_data_columns: |
73
|
|
|
if column not in list(filter_df["parameter"]): |
74
|
|
|
continue |
75
|
|
|
|
76
|
|
|
filter_ = filter_df[filter_df["parameter"] == column] |
77
|
|
|
lower, upper = ( |
78
|
|
|
filter_["lower bound"].values[0], |
79
|
|
|
filter_["upper bound"].values[0], |
80
|
|
|
) |
81
|
|
|
|
82
|
|
|
col_data = df[column] |
83
|
|
|
|
84
|
|
|
if isinstance(lower, numbers.Number): |
85
|
|
|
lower = float(lower) |
86
|
|
|
else: |
87
|
|
|
lower = np.min(col_data) |
88
|
|
|
|
89
|
|
|
if isinstance(upper, numbers.Number): |
90
|
|
|
upper = float(upper) |
91
|
|
|
else: |
92
|
|
|
upper = np.max(col_data) |
93
|
|
|
|
94
|
|
|
df = df[(df[column] >= lower) & (df[column] <= upper)] |
95
|
|
|
|
96
|
|
|
return df |
97
|
|
|
|
98
|
|
|
def plotly(self, progress_data, search_id): |
99
|
|
|
if progress_data is None or len(progress_data) <= 1: |
100
|
|
|
return None |
101
|
|
|
|
102
|
|
|
filter_df = self.search_id_dict[search_id]["filt_f"] |
103
|
|
|
|
104
|
|
|
progress_data = progress_data.drop( |
105
|
|
|
["nth_iter", "score_best", "nth_process", "best"], axis=1 |
106
|
|
|
) |
107
|
|
|
|
108
|
|
|
if filter_df is not None: |
109
|
|
|
progress_data = self.filter_data(progress_data, filter_df) |
110
|
|
|
|
111
|
|
|
# remove score |
112
|
|
|
prog_data_columns = list(progress_data.columns) |
113
|
|
|
prog_data_columns.remove("score") |
114
|
|
|
|
115
|
|
|
fig = px.parallel_coordinates( |
116
|
|
|
progress_data, |
117
|
|
|
dimensions=prog_data_columns, |
118
|
|
|
color="score", |
119
|
|
|
color_continuous_scale=color_scale, |
120
|
|
|
) |
121
|
|
|
fig.update_layout(autosize=False, width=1200, height=540) |
122
|
|
|
|
123
|
|
|
return fig |
124
|
|
|
|
125
|
|
|
def create_plots(self, search_id): |
126
|
|
|
progress_data = self.get_progress_data(search_id) |
127
|
|
|
|
128
|
|
|
pyplot_fig = self.pyplot(progress_data) |
129
|
|
|
plotly_fig = self.plotly(progress_data, search_id) |
130
|
|
|
|
131
|
|
|
return pyplot_fig, plotly_fig |
132
|
|
|
|
133
|
|
|
def create_info(self, search_id): |
134
|
|
|
progress_data = self.get_progress_data(search_id) |
135
|
|
|
if progress_data is None or len(progress_data) <= 1: |
136
|
|
|
return None |
137
|
|
|
|
138
|
|
|
progress_data_best = progress_data[progress_data["best"] == 1] |
139
|
|
|
|
140
|
|
|
progress_data_best = progress_data_best.drop( |
141
|
|
|
["nth_iter", "score_best", "nth_process", "best"], axis=1 |
142
|
|
|
) |
143
|
|
|
|
144
|
|
|
progress_data_best = progress_data_best.sort_values("score") |
145
|
|
|
last_best = progress_data_best.tail(5) |
146
|
|
|
last_best = last_best.rename( |
147
|
|
|
columns={ |
148
|
|
|
"score": "best 5 scores", |
149
|
|
|
} |
150
|
|
|
) |
151
|
|
|
|
152
|
|
|
return last_best |
153
|
|
|
|