From a12ad34be9942c1ccd27f4d5647fde17d520c635 Mon Sep 17 00:00:00 2001 From: UsovaMA Date: Wed, 8 May 2024 10:32:15 +0300 Subject: [PATCH] Dashboard (#191) * add current version of dashboard with example of usage * fix archive display speed and add upload mode for open another problem * add update version with redesign * partial refactoring and fixing after the meeting * post-meeting last corrections, eliminating outliers added * refactoring --------- Co-authored-by: Marina Usova --- dashboard/assets/iOptdash_light_.png | Bin 0 -> 94336 bytes dashboard/static_dashboard.py | 962 +++++++++++++++++++++++++++ examples/dash_example.py | 25 + requirements.txt | 5 + 4 files changed, 992 insertions(+) create mode 100644 dashboard/assets/iOptdash_light_.png create mode 100644 dashboard/static_dashboard.py create mode 100644 examples/dash_example.py diff --git a/dashboard/assets/iOptdash_light_.png b/dashboard/assets/iOptdash_light_.png new file mode 100644 index 0000000000000000000000000000000000000000..da8939a7521daa2965e5f0053de7824b41f80644 GIT binary patch literal 94336 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 i^#%Q39FNvD_>OQb)|aNw-~;#paC= 1.797692e+308].index, inplace=True) + self.__dfSDI.insert(loc=0, column='trial', value=np.arange(1, len(self.__dfSDI) + 1)) + self.__dfSDI_original = self.__dfSDI + + self.__fix_optimization_times() + self.__calculate_parameters_importance() + + del self.__data + self.__data = None + + def __calculate_parameters_importance(self): + min_obj_func = min(self.__dfSDI['objective_func']) + max_obj_func = max(self.__dfSDI['objective_func']) + + self.__importance = [] + for parameter in self.__parameters_names: + uniq_parameter_values = self.__dfSDI[parameter].unique() + importance_value = 0 + for value in uniq_parameter_values: + data = self.__dfSDI.loc[self.__dfSDI[parameter] == value] + importance_value += (max(data['objective_func']) - min(data['objective_func'])) + importance_value = importance_value / (len(uniq_parameter_values) * (max_obj_func - min_obj_func)) + self.__importance.append(round(importance_value, 2)) + + def __create_sidebar_navigator(self): + return html.Div( + [ + dbc.Navbar(dbc.Container([dbc.Col([dbc.Nav([ + dbc.NavItem(html.Img(src=r'assets/iOptdash_light_.png', alt='image', height="50px")), + dbc.NavItem(dbc.NavLink("Solution", href="/", active="exact")), + dbc.NavItem(dbc.NavLink("Analytics", href="/analytics", active="exact")), + dbc.NavItem(dbc.NavLink("Archive", href="/archive", active="exact"), className="me-auto"), + dbc.NavItem(dbc.NavLink("About", href="https://iopt.readthedocs.io/ru/latest")), + dbc.NavItem(dbc.NavLink("Github Source", href="https://github.com/aimclub/iOpt")), + html.Div( + [ + html.P(f"Eliminate outliers", style={'color': '#989898', 'font-size': '0.8em'}), + html.Td( + daq.BooleanSwitch(id='elimination-of-emissions', on=False, color='red') + ), + ], style={'width': '12%', 'position': 'right'} + ), + html.Div( + [ + html.P(f"Colorscheme", style={'color': '#989898', 'font-size': '0.8em'}), + dcc.Dropdown( + self.__color_scale_names, + "Ice", + id='color-theme' + ), + ], style={'width': '12%','position': 'right'} + ), + ]), + ] + )]), sticky="bottom", color="primary", dark=True), + ] + ) + + def __create_content_page(self): + return html.Div(id="page-content", style=CONTENT_STYLE) + + def __render_problem_description(self): + return html.Div(children=[ + html.H2('PROBLEM DESCRIPTION', + style={'textAlign': 'left'}), + html.P(f"Problem name: {self.__task_name}", style={'color': '#212121'}), + html.P(f"Number of functionalities: objective = 1, constraint = {self.__functional_count - 1}", + style={'color': '#212121'}), + html.P(f"Number of parameters: continuous = {len(self.__float_parameters_names)},\ + discrete = {len(self.__discrete_parameters_names)}", style={'color': '#212121'}), + dcc.Upload( + id='upload-data', + children=html.Div([ + 'Drag and Drop or ', + html.A('Select Files') + ]), + style={ + 'width': '95%', + 'height': '60px', + 'lineHeight': '60px', + 'borderWidth': '1px', + 'borderStyle': 'dashed', + 'borderRadius': '5px', + 'textAlign': 'center', + 'margin': '10px' + }, + multiple=True + ), + html.Div(id='data_from_json_file') + ], style={'width': '55%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}) + + def __render_parameters_description(self): + return html.Div(children=[ + html.H2('PARAMETERS USED', + style={'textAlign': 'left'}), + html.P(f"Required accuracy: eps = {self.__parameter_eps}", + style={'color': '#212121'}), + html.P(f"Reliability parameter: r = {self.__parameter_r}", + style={'color': '#212121'}), + html.P(f"Limiting the number of iterations: iters_limit = {self.__parameter_iters_limit}", + style={'color': '#212121'}), + ], style={'width': '45%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}) + + def __render_solution_description(self): + return html.Div(children=[ + html.H2('Solution', style={'textAlign': 'left'}), + html.P(f"Total trials number: {self.__trial_number} (global trials number - {self.__global_iter_number},\ + local trials number - {self.__local_iter_number})", style={'color': '#212121'}), + html.P(f"{round(self.__best_value, 6)}", style={'font-size': '2.0em', 'color': 'black'}), + html.P(f"Best point: {self.__best_float_point_dictionary}, {self.__best_discrete_point_dictionary}", + style={'color': '#212121'}), + html.P(f'Best trial number: {self.__best_trial_number}', style={'color': '#212121'}), + html.P(f"Accuracy: {round(self.__accuracy, 6)}", style={'color': '#212121'}), + html.P(f"*[c] - continuous variables, [d] - discrete variables", + style={'color': '#212121', 'font-size': '0.8em'}), + ], style={'width': '45%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}) + + def __render_optimization_time(self): + return html.Div(children=[ + html.H2('Optimization Time', style={'textAlign': 'left'}), + html.P(f"Total optimization time: {round(self.__solve_time, 3)} sec.", style={'color': '#212121'}), + html.Div(children=[ + dcc.Graph( + figure={ + "data": [{ + "x": self.__dfSDI['trial'], + "y": self.__optimization_time, + 'type': 'lines', + 'marker': {'color': self.__current_color} + }], + "layout": { + 'paper_bgcolor': '#FFFFFF', + 'plot_bgcolor': '#FFFFFF', + 'xaxis': {'anchor': 'y', 'title': {'text': 'trial number'}}, + 'yaxis': {'anchor': 'x', 'title': {'text': 'time before calculate trial, sec.'}} + }, + }, + config={'displayModeBar': True}, + ) + ]) + ], style={'width': '55%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF", }) + + def __hide_IQR(self, hide=False): + if hide: + Q1 = self.__dfSDI['objective_func'].quantile(0.25) + Q3 = self.__dfSDI['objective_func'].quantile(0.75) + mid = self.__dfSDI['objective_func'].median() + IQR = Q3 - Q1 + up = mid + 1.5 * IQR + self.__dfSDI = self.__dfSDI[(self.__dfSDI['objective_func'] <= up)] + else: + self.__dfSDI = self.__dfSDI_original + + def __render_iteration_characteristic(self): + return html.Div([ + html.H2('Objective Function Value Сhange', style={'textAlign': 'left'}), + html.Div(children=[ + html.Div(children=[ + dcc.Graph( + figure=((px.scatter( + self.__dfSDI, + x='trial', + y='objective_func', + color_discrete_sequence=[self.__current_color], + marginal_y="histogram", + trendline="expanding", + trendline_options=dict(function="min"))).update_layout( + legend={'orientation': "h", 'y': -0.25}, + xaxis={'anchor': 'x', 'title': {'text': 'trial number'}}, + yaxis={'anchor': 'y', 'title': {'text': 'objective function'}}, + paper_bgcolor='#FFFFFF', + plot_bgcolor='#FFFFFF' + ) + ), + config={ + 'displayModeBar': True, # True, False, 'hover' + }, + ) + ], style={'width': '100%'}), + ], style={'display': 'flex', 'flexDirection': 'row'}), + ], style={"background-color": "#FFFFFF", "border": "20px solid #FFFFFF", }) + + def __scatter_matrix_figure(self): + fig = px.scatter_matrix( + self.__dfSDI, + dimensions=self.__parameters_names, + color="objective_func", + opacity=0.7, + color_continuous_scale=self.__current_color_scale, + width=len(self.__parameters_names) * 240, + height=len(self.__parameters_names) * 240 + ) + fig.update_traces(diagonal_visible=False) + fig.update_layout(paper_bgcolor='#FFFFFF', plot_bgcolor='#FFFFFF') + return fig + + def __render_parameters_dependence(self): + return html.Div([ + html.H2('Parameters Dependence', style={'textAlign': 'left'}), + html.Div(children=[ + html.Div(children=[ + dcc.Graph( + figure=self.__scatter_matrix_figure(), + config={'displayModeBar': True}, + ) + ], style={'width': '100%'}), + ], style={'maxWidth': '100%', 'maxHeight': '600px', "overflow": "scroll"}), + ], style={'width': '100%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF", 'height': '750px'}) + + def __render_parameters_importance(self): + return html.Div([ + html.H2('Parameters Importance', style={'textAlign': 'left'}), + html.Div([ + dcc.Graph( + figure={ + 'data': [ + {'x': self.__parameters_names, + 'y': self.__importance, + 'orientation': 'v', + 'type': 'bar', + 'text': self.__importance, + 'textposition': 'outside', + 'textfont': "black", + 'text_auto': '.2s', + 'marker': { + 'color': self.__current_color, + 'line': {'color': self.__current_color, 'width': '1'} + } + }, + ], + 'layout': { + 'xaxis': { + 'anchor': 'y', + 'tickfont': {'size': '10'}, + 'tickangle': -90 + }, + 'yaxis': { + 'range': [0, 1], + 'anchor': 'x', + 'title': {'text': 'importance value'}, + 'tickfont': {'size': '10'} + }, + 'title': "Importance by contribution

to the scatter of the objective_func", + 'paper_bgcolor': '#FFFFFF', + 'plot_bgcolor': '#FFFFFF', + 'margin': dict(t=130, b=200, r=100) + } + }, + config={ + 'scrollZoom': True, # True, False + 'showTips': True, # True, False + 'displayModeBar': True, # True, False, 'hover' + }, + ) + ]) + ], style={'width': '40%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}) + + def __render_multidimensional_representation(self): + return html.Div(children=[ + html.H2('Multidimentional Visualization', style={'textAlign': 'left'}), + html.Div(children=[ + html.Div(children=[ + html.Br(), + html.Label('Parameters For Visualization'), + dcc.Dropdown( + self.__parameters_names, + self.__parameters_names, + id='mdf-parameter-names', + multi=True + ), + ], style={'width': '15%'}), + html.Div(children=[ + dcc.Graph( + id='multidimensional_figure', + config={'displayModeBar': True}, + ) + ], style={'width': '85%'}), + ], style={'display': 'flex', 'flexDirection': 'row', 'height': '90%'}) + ], style={"background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}) + + def __render_surface_and_level_lines(self): + return html.Div(children=[ + html.H2('Visualization in cross-section of the best discrete parameters', style={'textAlign': 'left'}), + html.Div([ + html.Div(children=[ + html.Br(), + html.Label('Type'), + dcc.Dropdown( + self.__figure_type_names, + self.__figure_type_names[0], + id='sllf-figure-type', + ), + html.Label('Calculate mode'), + dcc.Dropdown( + self.__calculation_type_names, + self.__calculation_type_names[0], + id='sllf-calculation-type', + ), + html.Label('X-axis parameter'), + dcc.Dropdown( + self.__float_parameters_names, + self.__float_parameters_names[0], + id='sllf-xaxis-parameter-name', + ), + html.Label('Y-axis parameter'), + dcc.Dropdown( + self.__float_parameters_names, + self.__float_parameters_names[1], + id='sllf-yaxis-parameter-name', + ), + html.Label('Show subplots'), + html.Td( + daq.BooleanSwitch(id='additional-figures', on=True, color="#3E59A5") + ) + ], style={'width': '20%'}), + html.Div(children=[ + dcc.Graph( + id='surface_or_lines_level_figure', + config={'displayModeBar': True}, + ) + ], style={'width': '75%'}), + ], style={'display': 'flex', 'flexDirection': 'row', 'width': '90%', 'height': '600px'}), + ], style={"background-color": "#FFFFFF", "border": "20px solid #FFFFFF", }) + + def __render_objective_function_values_scatter(self): + return html.Div(children=[ + html.H2('Scatter of Objective Function Values', style={'textAlign': 'left'}), + dcc.Tabs([ + dcc.Tab(label='Float Parameters', children=[ + html.Div([ + html.Div(children=[ + html.Br(), + html.Label('X-axis parameter'), + dcc.Dropdown( + self.__float_parameters_names, + self.__float_parameters_names[0], + id='csf-parameter-name', + style={'width': '60%'} + ), + dcc.Graph( + id='continuous_scatter_figure', + config={'displayModeBar': True}, + ) + ], style={'width': '100%'}), + ], style={'display': 'flex', 'flexDirection': 'row', 'width': '90%', 'height': '70%'}), + ]), + dcc.Tab(label='Discrete Parameters', children=[ + html.Div([ + html.Div(children=[ + html.Br(), + html.Label('X-axis parameter'), + dcc.Dropdown( + self.__discrete_parameters_names, + self.__discrete_parameters_names[0], + id='dsf-parameter-name', + style={'width': '60%'} + ), + dcc.Graph( + id='discrete_scatter_figure', + config={'displayModeBar': True}, + ) + ], style={'width': '100%'}), + ], style={'display': 'flex', 'flexDirection': 'row', 'width': '90%', 'height': '70%'}), + ]) + ], style={'width': '90%'}) + ], style={'width': '60%', "background-color": "#FFFFFF", "border": "20px solid #FFFFFF", }) + + def __render_archive(self, df): + return html.Div(children=[ + html.P(f"*[c] - continuous variables, [d] - discrete variables", + style={'text-align': 'right', 'color': '#212121', 'font-size': '0.8em'}), + html.H1('All Trials Archive', style={'textAlign': 'left'}), + html.Div( + [create_dash_table_from_dataframe(df)], + style={'maxWidth': '95%', 'maxHeight': '700px', "overflow": "scroll"} + ), + html.Div(id='archive_figure', style={'width': '95%'}) + ], style={"background-color": "#FFFFFF", "border": "20px solid #FFFFFF", }) + + def __render_page_content(self, pathname, color_theme, hide): + self.__hide_IQR(hide) + self.__current_color_scale = self.__color_themes_dict[color_theme] + self.__current_color = self.__current_color_scale[0] + if pathname == "/": + return [ + html.Div([ + self.__render_parameters_description(), + self.__render_problem_description(), + ], style={'display': 'flex', 'flexDirection': 'row'}), + html.Div([ + self.__render_solution_description(), + self.__render_optimization_time() + ], style={'display': 'flex', 'flexDirection': 'row'}), + self.__render_iteration_characteristic(), + ] + + elif pathname == "/archive": + if self.__mode == 'Release': + return [ + self.__render_archive( + self.__dfSDI_original[['trial'] + self.__parameters_names + ["objective_func"]] + ) + ] + elif self.__mode == 'Debug': + return [ + self.__render_archive( + self.__dfSDI_original + ) + ] + elif pathname == "/analytics": + return [ + html.Div(children=[ + html.P(f"*[c] - continuous variables, [d] - discrete variables", + style={'text-align': 'right', 'color': '#212121', 'font-size': '0.8em'}), + ], style={"background-color": "#FFFFFF", "border": "20px solid #FFFFFF"}), + self.__render_multidimensional_representation(), + self.__render_surface_and_level_lines(), + html.Div([ + self.__render_objective_function_values_scatter(), + self.__render_parameters_importance() + ], style={'display': 'flex', 'flexDirection': 'row'}), + html.Div([ + self.__render_parameters_dependence(), + ], style={'display': 'flex', 'flexDirection': 'row'}), + ] + + # If the user tries to reach a different page, return a 404 message + return dbc.Jumbotron( + [ + html.H1("404: Not found", className="text-danger"), + html.Hr(), + html.P(f"The pathname {pathname} was not recognised..."), + ] + ) + + def __update_discrete_scatter_figure(self, xaxis_column_name=None): + if xaxis_column_name == None: + xaxis_column_name = self.__discrete_parameters_names[0] + + fig = px.violin( + self.__dfSDI, + x=xaxis_column_name, + y='objective_func', + title="Scatter of objective function values

by selected discrete parameter", + color_discrete_sequence=[self.__current_color] + ) + fig.update_xaxes(title=xaxis_column_name) + fig.update_yaxes(title='objective_func') + fig.update_layout(paper_bgcolor='#FFFFFF', plot_bgcolor='#FFFFFF', showlegend=False) + return fig + + def __update_continuous_scatter_figure(self, xaxis_column_name=None): + if xaxis_column_name == None: + xaxis_column_name = self.__float_parameters_names[0] + + fig = px.scatter( + self.__dfSDI, + x=xaxis_column_name, + y='objective_func', + color=self.__dfSDI['trial'][::-1], + color_continuous_scale=list(reversed(self.__current_color_scale)), + title="Scatter of objective function values

by selected continuous parameter", + opacity=0.3 + ) + fig.update_xaxes(title=xaxis_column_name) + fig.update_yaxes(title='objective_func') + fig.update_layout(paper_bgcolor='#FFFFFF', plot_bgcolor='#FFFFFF', showlegend=False, + coloraxis_colorbar=dict(title="trial number")) + return fig + + def __calculate_data(self, xaxis_column_name, yaxis_column_name, calc): + if xaxis_column_name == None: + xaxis_column_name = self.__float_parameters_names[0] + if yaxis_column_name == None: + xaxis_column_name = self.__float_parameters_names[1] + + df = None + + # берем окрестность лучшего сочетания дискретных параметров + for param in self.__discrete_parameters_names: + df = self.__dfSDI.loc[self.__dfSDI[param] == self.__best_discrete_point_dictionary[param]] + + ''' + # берем окрестность лучших прочих непрерывных параметров + for param in self.float_parameters_names: + if (xaxis_column_name != param and yaxis_column_name != param): + df = df.loc[abs(df[param] - self.best_float_point_dictionary[param]) < self.parameter_eps] + ''' + + x = np.array(df[xaxis_column_name].values) + y = np.array(df[yaxis_column_name].values) + z = np.array(df['objective_func'].values) + + xi = None + yi = None + Z = None + + bounds_x = list(self.__float_parameters_bounds[ + (self.__float_parameters_names).index(xaxis_column_name) + ].values())[0] + bounds_y = list(self.__float_parameters_bounds[ + (self.__float_parameters_names).index(yaxis_column_name) + ].values())[0] + + if calc == 'interpolation': + xi = np.linspace(bounds_x[0], bounds_x[1], 150) + yi = np.linspace(bounds_y[0], bounds_y[1], 150) + X, Y = np.meshgrid(xi, yi) + Z = griddata((x, y), z, (X, Y), method='cubic') # "nearest", "linear", "natural", and "cubic" methods + elif calc == 'approximation': + nn = MLPRegressor( + activation='logistic', # can be tanh, identity, logistic, relu + solver='lbfgs', # can be lbfgs, sgd , adam + alpha=0.001, + hidden_layer_sizes=(40,), + max_iter=10000, + tol=10e-6, + random_state=10 + ) + + points = [list(x), list(y)] + points = list(map(list, zip(*points))) + + nn.fit(points, z) + xi = np.linspace(bounds_x[0], bounds_x[1], 150) + yi = np.linspace(bounds_y[0], bounds_y[1], 150) + X, Y = np.meshgrid(xi, yi) + + xy = np.c_[X.ravel(), Y.ravel()] + + Z = nn.predict(xy) + Z = Z.reshape(150, 150) + + return bounds_x, bounds_y, x, y, z, xi, yi, Z + + def __surface_figure(self, xaxis_column_name, yaxis_column_name, calc, show_additional_figs, xi, yi, Z, x, y, z): + if calc == 'interpolation' or calc == 'approximation': + surface = go.Surface(x=xi, y=yi, z=Z, + colorscale=self.__current_color_scale, + opacity=1, + colorbar=dict(title="objective_func") + ) + fig = go.Figure(data=[surface]) + if show_additional_figs: + fig.update_traces(contours_z=dict( + show=True, + usecolormap=True, + highlightcolor="limegreen", + project_z=True + )) + elif calc == 'none (by trials points)': + surface = go.Mesh3d(x=x, y=y, z=z, + showscale=True, + intensity=z, + colorscale=self.__current_color_scale, + opacity=1 + ) + fig = go.Figure(data=[surface]) + + fig.add_scatter3d(x=x, y=y, z=z, + mode='markers', + name='trials points', + marker=dict(size=2, color='red', opacity=0.7) + ) + fig.add_scatter3d( + x=[self.__best_float_point_dictionary[xaxis_column_name]], + y=[self.__best_float_point_dictionary[yaxis_column_name]], + z=[self.__best_value], + name='best trial point', + mode='markers', + marker=dict(size=3, color='green', opacity=1) + ) + fig.update_layout( + title='Surface in cross-section of the '+str(self.__best_discrete_point_dictionary), + scene=dict(xaxis_title=xaxis_column_name, yaxis_title=yaxis_column_name, zaxis_title='objective_func'), + paper_bgcolor='#FFFFFF', + plot_bgcolor='#FFFFFF', + showlegend=False, + height=590, + template="none" + ) + return fig + + def __lines_level_figure(self, xaxis_column_name, yaxis_column_name, calc, show_additional_figs, bounds_x, bounds_y, xi, yi, Z, x, y, z): + if calc == 'interpolation' or calc == 'approximation': + fig = go.Figure(data=[go.Contour(x=xi, y=yi, z=Z, + colorscale=self.__current_color_scale, + colorbar=dict(title='objective_func') + )]) + elif calc == 'none (by trials points)': + fig = go.Figure(data=[go.Contour(x=x, y=y, z=z, + colorscale=self.__current_color_scale, + colorbar=dict(title='objective_func', titleside='right') + )]) + + fig.add_scatter(x=x, y=y, + mode='markers', + name='trials points', + marker=dict(size=2, color='red', opacity=0.7) + ) + fig.add_scatter( + x=[self.__best_float_point_dictionary[xaxis_column_name]], + y=[self.__best_float_point_dictionary[yaxis_column_name]], + mode='markers', + name='best trial point', + marker=dict(size=4, color='green', opacity=1) + ) + + fig.update_layout( + title='Heatmap in cross-section of the '+str(self.__best_discrete_point_dictionary), + paper_bgcolor='#FFFFFF', + plot_bgcolor='#FFFFFF', + showlegend=True, + height=590, + legend={'orientation': "h"}, + xaxis_range=[bounds_x[0], bounds_x[1]], yaxis_range=[bounds_y[0], bounds_y[1]], + xaxis_title=xaxis_column_name, + yaxis_title=yaxis_column_name + ) + if show_additional_figs: + fig.add_trace(go.Histogram( + y=y, + xaxis='x2', + marker=dict(color=self.__current_color), + name=yaxis_column_name + ' values histogram' + )) + fig.add_trace(go.Histogram( + x=x, + yaxis='y2', + marker=dict(color=self.__current_color), + name=xaxis_column_name + ' values histogram' + )) + fig.update_layout( + xaxis_domain=[0, 0.85], + yaxis_domain=[0, 0.85], + xaxis2=dict(zeroline=False, domain=[0.85, 1], showgrid=False), + yaxis2=dict(zeroline=False, domain=[0.85, 1], showgrid=False), + bargap=0, + hovermode='closest', + ) + return fig + + def __update_surface_or_lines_level_figure(self, xaxis_column_name=None, yaxis_column_name=None, type='3D Surface', + calc='interpolation', show_additional_figs=True): + bounds_x, bounds_y, x, y, z, xi, yi, Z = self.__calculate_data(xaxis_column_name, yaxis_column_name, calc) + if type == '3D Surface': + return self.__surface_figure(xaxis_column_name, yaxis_column_name, calc, show_additional_figs, + xi, yi, Z, x, y, z) + elif type == 'Heatmap': + return self.__lines_level_figure(xaxis_column_name, yaxis_column_name, calc, show_additional_figs, + bounds_x, bounds_y, xi, yi, Z, x, y, z) + + def __update_multidimensional_figure(self, xaxis_column_name=None): + if xaxis_column_name == None: + xaxis_column_name = self.__parameters_names + xaxis_column_name = ['objective_func'] + xaxis_column_name + + xaxis_column_name_dict = {} + for name in xaxis_column_name: + if name in self.__discrete_parameters_names: + self.__dfSDI[name + '_cat'] = self.__dfSDI[name].astype('category').cat.codes + replace = name+'_cat' + else: + replace = name + xaxis_column_name_dict[replace] = name + + + fig = px.parallel_coordinates( + self.__dfSDI, + color="objective_func", + dimensions=xaxis_column_name_dict.keys(), + labels=xaxis_column_name_dict, + color_continuous_scale=self.__current_color_scale + ) + + fig.update_layout( + xaxis=dict(title='parameters', ticktext=xaxis_column_name), + yaxis=dict(title='objective_func'), + paper_bgcolor='#FFFFFF', + plot_bgcolor='#FFFFFF' + ) + + fig.update_traces(unselected_line_opacity=0.5, selector=dict(type='parcoords')) + + return fig + + def __read_data_from_json(self, contents): + if self.__init and (contents is not None): + content_type, content_string = contents[0].split(',') + decoded = base64.b64decode(content_string) + self.__data = json.loads(decoded) + self.launch() + else: + self.__init = True + return html.Div(id='hidden-div', style={'display':'none'}) + + def __update_archive_figure(self, rows, derived_virtual_selected_rows): + if derived_virtual_selected_rows is None: + derived_virtual_selected_rows = [] + + dff = self.__dfSDI_original if rows is None else pd.DataFrame(rows) + + ids = [] + check = list(~dff['trial'].isin(self.__dfSDI['trial'])) + for i in range(len(dff)): + if check[i]: + ids.append(i) + + colors = ['#31B37C' if i in derived_virtual_selected_rows else + "red" if i in ids else + self.__current_color + for i in range(len(dff))] + + return [ + dcc.Graph( + figure={ + "data": [ + { + "x": dff['trial'], + "y": dff['objective_func'], + "type": "bar", + "marker": {"color": colors}, + } + ], + "layout": { + "xaxis": {"automargin": True, "title": "trial"}, + "yaxis": { + "automargin": True, + "title": {"text": "objective_func"} + }, + "height": 250, + "weight": "95%", + "margin": {"t": 10, "l": 10, "r": 10}, + "paper_bgcolor": '#FFFFFF', + "plot_bgcolor": '#FFFFFF' + }, + }, + ) + ] diff --git a/examples/dash_example.py b/examples/dash_example.py new file mode 100644 index 0000000..7a1914f --- /dev/null +++ b/examples/dash_example.py @@ -0,0 +1,25 @@ +from problems.rastriginInt import RastriginInt +from iOpt.solver import Solver +from iOpt.solver_parametrs import SolverParameters + +from dashboard.static_dashboard import StaticDashboard + +if __name__ == "__main__": + # create the problem + problem = RastriginInt(5, 2) + + # add solver parameters + params = SolverParameters(r=2.1, eps=0.01) + + # create solver + solver = Solver(problem, parameters=params) + + # solve problem + solver.solve() + + # save optimization progress + log = solver.save_progress('log_RastriginInt_5-2_2.1_0.01_1.json') + + # visualizate optimization progress + dashboard = StaticDashboard('log_RastriginInt_5-2_2.1_0.01_1.json') + dashboard.launch() diff --git a/requirements.txt b/requirements.txt index b1cac43..c5aeb5e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,8 @@ sphinxcontrib-details-directive autodocsumm pathos multiprocess +dash +dash-bootstrap-components +plotly +pandas +scipy