pyfemtet 0.4.17__py3-none-any.whl → 0.4.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyfemtet might be problematic. Click here for more details.

Files changed (55) hide show
  1. pyfemtet/__init__.py +1 -1
  2. pyfemtet/_test_util.py +31 -35
  3. pyfemtet/message/locales/ja/LC_MESSAGES/messages.po +5 -5
  4. pyfemtet/opt/femprj_sample/.gitignore +2 -0
  5. pyfemtet/opt/femprj_sample/ParametricIF_test_result.reccsv +10 -10
  6. pyfemtet/opt/femprj_sample/cad_ex01_NX_test_result.reccsv +23 -13
  7. pyfemtet/opt/femprj_sample/cad_ex01_SW_test_result.reccsv +23 -13
  8. pyfemtet/opt/femprj_sample/gal_ex58_parametric_test_result.reccsv +11 -11
  9. pyfemtet/opt/femprj_sample/gau_ex08_parametric_test_result.reccsv +20 -20
  10. pyfemtet/opt/femprj_sample/her_ex40_parametric_test_result.reccsv +15 -15
  11. pyfemtet/opt/femprj_sample/paswat_ex1_parametric_test_result.reccsv +15 -15
  12. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14.pdt +0 -0
  13. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
  14. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial1.pdt +0 -0
  15. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
  16. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial10.pdt +0 -0
  17. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
  18. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
  19. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
  20. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
  21. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
  22. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
  23. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
  24. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
  25. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
  26. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
  27. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
  28. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial2.pdt +0 -0
  29. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
  30. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial3.pdt +0 -0
  31. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
  32. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial4.pdt +0 -0
  33. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
  34. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial5.pdt +0 -0
  35. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
  36. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial6.pdt +0 -0
  37. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
  38. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial7.pdt +0 -0
  39. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
  40. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial8.pdt +0 -0
  41. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
  42. pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial9.pdt +0 -0
  43. pyfemtet/opt/femprj_sample/wat_ex14_parametric_test_result.reccsv +15 -15
  44. pyfemtet/opt/opt/_optuna.py +29 -11
  45. pyfemtet/opt/visualization/complex_components/control_femtet.py +1 -0
  46. pyfemtet/opt/visualization/complex_components/main_figure_creator.py +1 -1
  47. pyfemtet/opt/visualization/complex_components/pm_graph.py +61 -218
  48. pyfemtet/opt/visualization/complex_components/pm_graph_creator.py +19 -8
  49. pyfemtet/opt/visualization/result_viewer/pages.py +49 -20
  50. {pyfemtet-0.4.17.dist-info → pyfemtet-0.4.18.dist-info}/METADATA +1 -1
  51. {pyfemtet-0.4.17.dist-info → pyfemtet-0.4.18.dist-info}/RECORD +54 -54
  52. pyfemtet/opt/femprj_sample/tutorial.femprj +0 -0
  53. {pyfemtet-0.4.17.dist-info → pyfemtet-0.4.18.dist-info}/LICENSE +0 -0
  54. {pyfemtet-0.4.17.dist-info → pyfemtet-0.4.18.dist-info}/WHEEL +0 -0
  55. {pyfemtet-0.4.17.dist-info → pyfemtet-0.4.18.dist-info}/entry_points.txt +0 -0
@@ -105,14 +105,15 @@ class OptunaOptimizer(AbstractOptimizer):
105
105
  raise optuna.TrialPruned() # set TrialState PRUNED because FAIL causes similar candidate loop.
106
106
 
107
107
  # 拘束 attr の更新
108
- _c = [] # 非正なら OK
109
- for (name, cns), c_value in zip(self.constraints.items(), c):
110
- lb, ub = cns.lb, cns.ub
111
- if lb is not None: # fun >= lb <=> lb - fun <= 0
112
- _c.append(lb - c_value)
113
- if ub is not None: # ub >= fun <=> fun - ub <= 0
114
- _c.append(c_value - ub)
115
- trial.set_user_attr('constraint', _c)
108
+ if len(self.constraints) > 0:
109
+ _c = [] # 非正なら OK
110
+ for (name, cns), c_value in zip(self.constraints.items(), c):
111
+ lb, ub = cns.lb, cns.ub
112
+ if lb is not None: # fun >= lb <=> lb - fun <= 0
113
+ _c.append(lb - c_value)
114
+ if ub is not None: # ub >= fun <=> fun - ub <= 0
115
+ _c.append(c_value - ub)
116
+ trial.set_user_attr('constraint', _c)
116
117
 
117
118
  # 中断の確認 (解析中に interrupt されている場合対策)
118
119
  if self.entire_status.get() == OptimizationStatus.INTERRUPTING:
@@ -124,7 +125,18 @@ class OptunaOptimizer(AbstractOptimizer):
124
125
  return tuple(_y)
125
126
 
126
127
  def _constraint(self, trial):
127
- return trial.user_attrs['constraint'] if 'constraint' in trial.user_attrs.keys() else (1,) # infeasible
128
+ # if break trial without weak constraint calculation, return 1 (as infeasible).
129
+ if 'constraint' in trial.user_attrs.keys():
130
+ return trial.user_attrs['constraint']
131
+ else:
132
+ _c = []
133
+ for name, cns in self.constraints.items():
134
+ lb, ub = cns.lb, cns.ub
135
+ if lb is not None:
136
+ _c.append(1.)
137
+ if ub is not None:
138
+ _c.append(1.)
139
+ return _c
128
140
 
129
141
  def _setup_before_parallel(self):
130
142
  """Create storage, study and set initial parameter."""
@@ -235,9 +247,15 @@ class OptunaOptimizer(AbstractOptimizer):
235
247
  seed += self.subprocess_idx
236
248
 
237
249
  # restore sampler
250
+ if len(self.constraints) > 0:
251
+ self.sampler_kwargs.update(
252
+ constraints_func=self._constraint
253
+ )
254
+ if seed is not None:
255
+ self.sampler_kwargs.update(
256
+ seed=seed
257
+ )
238
258
  sampler = self.sampler_class(
239
- seed=seed,
240
- constraints_func=self._constraint,
241
259
  **self.sampler_kwargs
242
260
  )
243
261
 
@@ -49,6 +49,7 @@ class FemtetControl(AbstractPage):
49
49
  id='connect-femtet-button',
50
50
  outline=True,
51
51
  color='primary',
52
+ className="position-relative", # need to show badge
52
53
  )
53
54
 
54
55
  # noinspection PyAttributeOutsideInit
@@ -61,7 +61,7 @@ def get_hypervolume_plot(_: History, df):
61
61
  fig.update_layout(
62
62
  dict(
63
63
  title_text=Msg.GRAPH_TITLE_HYPERVOLUME,
64
- transition_duration=1000,
64
+ # transition_duration=1000, # Causes graph freeze on tab change
65
65
  xaxis_title=Msg.GRAPH_AXIS_LABEL_TRIAL,
66
66
  yaxis_title='hypervolume',
67
67
  )
@@ -2,7 +2,7 @@
2
2
  from dash.development.base_component import Component
3
3
 
4
4
  # callback
5
- from dash import Output, Input, State, no_update, callback_context, ALL, MATCH
5
+ from dash import Output, Input, State, no_update, callback_context, ALL
6
6
  from dash.exceptions import PreventUpdate
7
7
 
8
8
  # components
@@ -15,13 +15,14 @@ import pandas as pd
15
15
  import plotly.graph_objs as go
16
16
 
17
17
  # the others
18
+ from enum import Enum, auto
18
19
  import os
19
20
  import base64
20
21
  import json
21
22
  import numpy as np
22
23
 
23
24
  from pyfemtet.opt.visualization.complex_components.pm_graph_creator import PredictionModelCreator
24
- from pyfemtet.opt.visualization.base import PyFemtetApplicationBase, AbstractPage, logger
25
+ from pyfemtet.opt.visualization.base import AbstractPage, logger
25
26
  from pyfemtet.message import Msg
26
27
 
27
28
 
@@ -60,6 +61,11 @@ class PredictionModelGraph(AbstractPage):
60
61
 
61
62
  """
62
63
 
64
+ class CommandState(Enum):
65
+ ready = auto()
66
+ recalc = auto()
67
+ redraw = auto()
68
+
63
69
  def __init__(self):
64
70
  self.rsm_creator: PredictionModelCreator = PredictionModelCreator()
65
71
  super().__init__()
@@ -97,6 +103,8 @@ class PredictionModelGraph(AbstractPage):
97
103
  # self.selection_data = html.Data(id='selection-data', **{self.selection_data_property: {}})
98
104
 
99
105
  # update rsm button
106
+ self.command_manager_prop = 'data-command-manager'
107
+ self.command_manager = html.Data(**{self.command_manager_prop: self.CommandState.ready.value})
100
108
  self.fit_rsm_button_spinner = dbc.Spinner(size='sm', spinner_style={'display': 'none'})
101
109
  self.fit_rsm_button = dbc.Button([self.fit_rsm_button_spinner, Msg.LABEL_OF_CREATE_PREDICTION_MODEL_BUTTON], color='success')
102
110
  self.redraw_graph_button_spinner = dbc.Spinner(size='sm', spinner_style={'display': 'none'})
@@ -136,7 +144,13 @@ class PredictionModelGraph(AbstractPage):
136
144
 
137
145
  self.card_footer = dbc.CardFooter(
138
146
  children=[
139
- dbc.Stack([self.fit_rsm_button, self.redraw_graph_button], direction='horizontal', gap=2),
147
+ dbc.Stack(
148
+ children=[
149
+ self.fit_rsm_button,
150
+ self.redraw_graph_button,
151
+ self.command_manager
152
+ ],
153
+ direction='horizontal', gap=2),
140
154
  *dropdown_rows,
141
155
  self.slider_container,
142
156
  self.slider_stack_data,
@@ -166,12 +180,19 @@ class PredictionModelGraph(AbstractPage):
166
180
 
167
181
  app = self.application.app
168
182
 
183
+ # ===== control button disabled and calculation =====
184
+ """
185
+ [fit button clicked] ────┬──> [disabled] ─┬─> [calc] ─╮
186
+ [redraw button clicked] ─┘ └───────────┴─> [redraw] ─> [enabled]
187
+ """
188
+
169
189
  # ===== disable fit buttons when clicked =====
170
190
  @app.callback(
171
191
  Output(self.fit_rsm_button_spinner, 'spinner_style', allow_duplicate=True),
172
192
  Output(self.fit_rsm_button, 'disabled', allow_duplicate=True),
173
193
  Output(self.redraw_graph_button_spinner, 'spinner_style', allow_duplicate=True),
174
194
  Output(self.redraw_graph_button, 'disabled', allow_duplicate=True),
195
+ Output(self.command_manager, self.command_manager_prop, allow_duplicate=True),
175
196
  Input(self.fit_rsm_button, 'n_clicks'),
176
197
  Input(self.redraw_graph_button, 'n_clicks'),
177
198
  State(self.fit_rsm_button_spinner, 'spinner_style'),
@@ -179,28 +200,41 @@ class PredictionModelGraph(AbstractPage):
179
200
  prevent_initial_call=True,
180
201
  )
181
202
  def disable_fit_button(_1, _2, state1, state2):
203
+ # spinner visibility
182
204
  if 'display' in state1.keys(): state1.pop('display')
183
205
  if 'display' in state2.keys(): state2.pop('display')
184
- return state1, True, state2, True
206
+
207
+ # recalc or redraw
208
+ if callback_context.triggered_id == self.fit_rsm_button.id:
209
+ command = self.CommandState.recalc.value
210
+ else:
211
+ command = self.CommandState.redraw.value
212
+
213
+ return state1, True, state2, True, command
185
214
 
186
215
  # ===== recreate RSM =====
187
216
  @app.callback(
188
- Output(self.redraw_graph_button, 'n_clicks'),
189
- Input(self.fit_rsm_button, 'n_clicks'),
217
+ Output(self.command_manager, self.command_manager_prop, allow_duplicate=True),
218
+ Output(self.graph, 'figure', allow_duplicate=True), # for show spinner during calculation
219
+ Input(self.command_manager, self.command_manager_prop),
190
220
  prevent_initial_call=True,
191
221
  )
192
- def recalculate_rsm(*args):
222
+ def recalculate_rsm(command):
193
223
  # just in case
194
224
  if callback_context.triggered_id is None:
195
225
  raise PreventUpdate
196
226
 
227
+ # check command
228
+ if command != self.CommandState.recalc.value:
229
+ raise PreventUpdate
230
+
197
231
  # load history
198
232
  if self.application.history is None:
199
- return 1 # error handling in the next `redraw_graph()` callback
233
+ return self.CommandState.redraw.value, no_update # error handling in the next `redraw_graph()` callback
200
234
 
201
235
  # check history
202
236
  if len(self.data_accessor()) == 0:
203
- return 1 # error handling in the next `redraw_graph()` callback
237
+ return self.CommandState.redraw.value, no_update # error handling in the next `redraw_graph()` callback
204
238
 
205
239
  # create model
206
240
  self.rsm_creator.fit(
@@ -208,13 +242,14 @@ class PredictionModelGraph(AbstractPage):
208
242
  self.data_accessor(),
209
243
  )
210
244
 
211
- return 1
245
+ return self.CommandState.redraw.value, no_update
212
246
 
213
247
  # ===== Update Graph =====
214
248
  @app.callback(
215
249
  Output(self.graph, 'figure'),
250
+ Output(self.command_manager, self.command_manager_prop),
216
251
  # Output(self.data_length.id, self.data_length_prop), # To determine whether Process Monitor should update the graph, the main graph remembers the current amount of data.
217
- Input(self.redraw_graph_button, 'n_clicks'),
252
+ Input(self.command_manager, self.command_manager_prop),
218
253
  State(self.tabs, 'active_tab'),
219
254
  State(self.axis1_prm_dropdown, 'label'),
220
255
  State(self.axis2_prm_dropdown, 'label'),
@@ -223,26 +258,30 @@ class PredictionModelGraph(AbstractPage):
223
258
  State({'type': 'prm-slider', 'index': ALL}, 'value'),
224
259
  prevent_initial_call=True,
225
260
  )
226
- def redraw_graph(_1, active_tab_id, axis1_label, axis2_label, axis3_label, _2, prm_values):
261
+ def redraw_graph(command, active_tab_id, axis1_label, axis2_label, axis3_label, _2, prm_values):
227
262
  # just in case
228
263
  if callback_context.triggered_id is None:
229
264
  raise PreventUpdate
230
265
 
266
+ # check command
267
+ if command != self.CommandState.redraw.value:
268
+ raise PreventUpdate
269
+
231
270
  # load history
232
271
  if self.application.history is None:
233
272
  logger.error(Msg.ERR_NO_HISTORY_SELECTED)
234
- return go.Figure() # to re-enable buttons, fire callback chain
273
+ return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
235
274
  prm_names = self.application.history.prm_names
236
275
 
237
276
  # check history
238
277
  if len(self.data_accessor()) == 0:
239
278
  logger.error(Msg.ERR_NO_FEM_RESULT)
240
- return go.Figure() # to re-enable buttons, fire callback chain
279
+ return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
241
280
 
242
281
  # check fit
243
282
  if not hasattr(self.rsm_creator, 'history'):
244
283
  logger.error(Msg.ERR_NO_PREDICTION_MODEL)
245
- return go.Figure() # to re-enable buttons, fire callback chain
284
+ return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
246
285
 
247
286
  # get indices to remove
248
287
  idx1 = prm_names.index(axis1_label) if axis1_label in prm_names else None
@@ -266,7 +305,7 @@ class PredictionModelGraph(AbstractPage):
266
305
  prm_name_2=axis2_label,
267
306
  )
268
307
 
269
- return fig
308
+ return fig, self.CommandState.ready.value
270
309
 
271
310
  # ===== When the graph is updated, enable buttons =====
272
311
  @app.callback(
@@ -274,12 +313,14 @@ class PredictionModelGraph(AbstractPage):
274
313
  Output(self.fit_rsm_button_spinner, 'spinner_style', allow_duplicate=True),
275
314
  Output(self.redraw_graph_button, 'disabled', allow_duplicate=True),
276
315
  Output(self.redraw_graph_button_spinner, 'spinner_style', allow_duplicate=True),
277
- Input(self.graph, 'figure'),
316
+ Input(self.command_manager, self.command_manager_prop),
278
317
  State(self.fit_rsm_button_spinner, 'spinner_style'),
279
318
  State(self.redraw_graph_button_spinner, 'spinner_style'),
280
319
  prevent_initial_call=True,
281
320
  )
282
- def enable_buttons(_, state1, state2):
321
+ def enable_buttons(command, state1, state2):
322
+ if command != self.CommandState.ready.value:
323
+ raise PreventUpdate
283
324
  state1.update({'display': 'none'})
284
325
  state2.update({'display': 'none'})
285
326
  return False, state1, False, state2
@@ -369,7 +410,7 @@ class PredictionModelGraph(AbstractPage):
369
410
  Output(self.axis3_obj_dropdown, 'label'),
370
411
  Output({'type': 'prm-slider-stack', 'index': ALL}, 'style'), # visibility of slider
371
412
  Output('prm-axis-2-dropdown', 'hidden'),
372
- Input({'type': 'axis1-dropdown-menu-item', 'index': ALL}, 'n_clicks'), # when the dropdown item is clicked
413
+ Input({'type': 'axis1-dropdown-menu-item', 'index': ALL}, 'n_clicks'), # when the dropdown item is clicked
373
414
  Input({'type': 'axis2-dropdown-menu-item', 'index': ALL}, 'n_clicks'),
374
415
  Input({'type': 'axis3-dropdown-menu-item', 'index': ALL}, 'n_clicks'),
375
416
  Input(self.axis1_prm_dropdown, 'children'), # for callback chain timing
@@ -383,7 +424,7 @@ class PredictionModelGraph(AbstractPage):
383
424
  # argument processing
384
425
  current_ax1_label = args[4]
385
426
  current_ax2_label = args[5]
386
- current_ax3_label = args[6]
427
+ # current_ax3_label = args[6]
387
428
  current_styles: list[dict] = args[7]
388
429
 
389
430
  # just in case
@@ -453,204 +494,6 @@ class PredictionModelGraph(AbstractPage):
453
494
 
454
495
  return tuple(ret.values())
455
496
 
456
- # # # ===== update axis1-prm-dropdown =====
457
- # # @app.callback(
458
- # # Output(self.axis1_prm_dropdown, 'label', allow_duplicate=True),
459
- # # Input(self.location, self.location.Prop.pathname),
460
- # # [Input(item, 'n_clicks') for item in self.prm1_items],
461
- # # State(self.axis2_prm_dropdown, 'label'),
462
- # # prevent_initial_call=True,
463
- # # )
464
- # # def update_prm1_dropdown_menu_label(*args):
465
- # # prm2_label = args[-1]
466
- # #
467
- # # # 一応
468
- # # if callback_context.triggered_id is None:
469
- # # raise PreventUpdate
470
- # #
471
- # # # load history
472
- # # if self.application.history is None:
473
- # # return 'History is not selected.'
474
- # # prm_names = self.application.history.prm_names
475
- # #
476
- # # # 1st parameter on loaded
477
- # # if callback_context.triggered_id == self.location.id:
478
- # # return prm_names[0]
479
- # #
480
- # # # clicked
481
- # # for i, item in enumerate(self.prm1_items):
482
- # # if item.id == callback_context.triggered_id:
483
- # # if prm_names[i] != prm2_label:
484
- # # return prm_names[i]
485
- # # else:
486
- # # logger.error('Cannot select same parameter')
487
- # # raise PreventUpdate
488
- # #
489
- # # # something wrong
490
- # # # logger.debug('something wrong in `update_dropdown_menu_label`')
491
- # # raise PreventUpdate
492
- # #
493
- # # # ===== update axis2-prm-dropdown =====
494
- # # @app.callback(
495
- # # Output(self.axis2_prm_dropdown, 'label', allow_duplicate=True),
496
- # # Output(self.axis2_prm_dropdown, 'hidden', allow_duplicate=True),
497
- # # Input(self.location, self.location.Prop.pathname),
498
- # # [Input(item, 'n_clicks') for item in self.prm2_items],
499
- # # State(self.axis1_prm_dropdown, 'label'),
500
- # # prevent_initial_call=True,
501
- # # )
502
- # # def update_prm2_dropdown_menu_label(*args):
503
- # # prm1_label = args[-1]
504
- # #
505
- # # # 一応
506
- # # if callback_context.triggered_id is None:
507
- # # raise PreventUpdate
508
- # #
509
- # # # load history
510
- # # if self.application.history is None:
511
- # # return 'History is not selected.', no_update
512
- # # prm_names = self.application.history.prm_names
513
- # #
514
- # # # disable axis2 if only 1 parameter optimization
515
- # # if len(prm_names) == 1:
516
- # # return no_update, True
517
- # #
518
- # # # 2nd parameter on loaded
519
- # # if callback_context.triggered_id == self.location.id:
520
- # # return prm_names[1], False
521
- # #
522
- # # # clicked
523
- # # for i, item in enumerate(self.prm2_items):
524
- # # if item.id == callback_context.triggered_id:
525
- # # if prm_names[i] != prm1_label:
526
- # # return prm_names[i], False
527
- # # else:
528
- # # logger.error('Cannot select same parameter')
529
- # # raise PreventUpdate
530
- # #
531
- # # # something wrong
532
- # # # logger.debug('something wrong in `update_dropdown_menu_label`')
533
- # # raise PreventUpdate
534
- # #
535
- # # # ===== update axis3-obj-dropdown =====
536
- # # @app.callback(
537
- # # Output(self.axis3_obj_dropdown, 'label', allow_duplicate=True),
538
- # # Input(self.location, self.location.Prop.pathname),
539
- # # [Input(item, 'n_clicks') for item in self.obj_items],
540
- # # prevent_initial_call=True,
541
- # # )
542
- # # def update_obj_dropdown_menu_label(*args):
543
- # # # 一応
544
- # # if callback_context.triggered_id is None:
545
- # # raise PreventUpdate
546
- # #
547
- # # if self.application.history is None:
548
- # # return 'History is not selected.'
549
- # #
550
- # # obj_names = self.application.history.obj_names
551
- # #
552
- # # # 1st objective on loaded
553
- # # if callback_context.triggered_id == self.location.id:
554
- # # return obj_names[0]
555
- # #
556
- # # # clicked
557
- # # for i, item in enumerate(self.obj_items):
558
- # # if item.id == callback_context.triggered_id:
559
- # # return obj_names[i]
560
- # #
561
- # # # something wrong
562
- # # # logger.debug('something wrong in `update_dropdown_menu_label`')
563
- # # raise PreventUpdate
564
- #
565
- # # ===== setup sliders =====
566
- # @app.callback(
567
- # Output(self.slider_container, 'children'),
568
- # Output(self.slider_stack_data, self.slider_stack_data_prop),
569
- # Input(self.location, self.location.Prop.pathname),
570
- # Input(self.axis1_prm_dropdown, 'label'),
571
- # Input(self.axis2_prm_dropdown, 'label'),
572
- # State(self.slider_stack_data, self.slider_stack_data_prop),
573
- # prevent_initial_call=True,
574
- # )
575
- # def update_sliders(_, label1, label2, slider_values):
576
- # # Just in case
577
- # if callback_context.triggered_id is None:
578
- # raise PreventUpdate
579
- #
580
- # # load history
581
- # if self.application.history is None:
582
- # return 'History is not selected.', no_update
583
- # prm_names: list = list(self.application.history.prm_names) # shallow copy
584
- #
585
- # prm_names.remove(label1) if label1 in prm_names else None
586
- # prm_names.remove(label2) if label2 in prm_names else None
587
- #
588
- # out = []
589
- # for prm_name in prm_names:
590
- # # get ub and lb
591
- # lb_column = prm_name + '_lower_bound'
592
- # ub_column = prm_name + '_upper_bound'
593
- # # get minimum lb and maximum ub
594
- # df = self.data_accessor()
595
- # lb = df[lb_column].min()
596
- # ub = df[ub_column].max()
597
- # # if lb or ub is not specified, use value instead
598
- # lb = df[prm_name].min() if np.isnan(lb) else lb
599
- # ub = df[prm_name].max() if np.isnan(ub) else ub
600
- # # create slider
601
- # if prm_name in slider_values.keys():
602
- # value = slider_values[prm_name]
603
- # print('-----')
604
- # print(slider_values)
605
- # else:
606
- # value = (lb + ub) / 2
607
- # slider_values.update({'value': value})
608
- # print('ooooo')
609
- # print(lb, ub)
610
- # print('=====')
611
- # print(value)
612
- # stack = dbc.Stack(
613
- # children=[
614
- # html.Div(f'{prm_name}: '),
615
- # dcc.Slider(
616
- # lb,
617
- # ub,
618
- # marks=None,
619
- # value=value,
620
- # id={'type': f'prm-slider', 'index': prm_name},
621
- # tooltip={"placement": "bottom", "always_visible": True},
622
- # )
623
- # ]
624
- # )
625
- # out.append(stack)
626
- #
627
- # return out, slider_values
628
- #
629
- # # ===== update slider values =====
630
- # @app.callback(
631
- # Output(self.slider_stack_data, self.slider_stack_data_prop, allow_duplicate=True),
632
- # Input([{'type': 'prm-slider', 'index': prm_name}, 'value') ],
633
- # prevent_initial_call=True,
634
- # )
635
- # def update_slider_values(values):
636
- # # Just in case
637
- # if callback_context.triggered_id is None:
638
- # raise PreventUpdate
639
- #
640
- # # load history
641
- # if self.application.history is None:
642
- # return 'History is not selected.', no_update
643
- # prm_names = self.application.history.prm_names
644
- #
645
- # print('==========')
646
- # print(callback_context.triggered_id)
647
- # print(callback_context.triggered_prop_ids)
648
- # print(callback_context.triggered)
649
- # print(values)
650
- # float = callback_context.triggered[0]['value'][0]
651
- #
652
- # return {}
653
-
654
497
  def create_formatted_parameter(self, row) -> Component:
655
498
  metadata = self.application.history.metadata
656
499
  pd.options.display.float_format = '{:.4e}'.format
@@ -117,26 +117,38 @@ class PredictionModelCreator:
117
117
 
118
118
  # set opacity by its distance
119
119
  def set_opacity(trace):
120
- trace.marker.color = [f'rgba(0, 0, 0, {o})' for o in opacity]
120
+ trace.marker.color = [f'rgba(0, 0, 0, {o: .2f})' for o in opacity]
121
121
  fig.for_each_trace(set_opacity)
122
122
 
123
123
  # main RSM
124
124
  if prm_name_2:
125
125
  contours = dict(
126
126
  x=dict(
127
- highlight=False, show=True, color='blue',
127
+ highlight=True, show=True, color='blue',
128
128
  start=lb1, end=ub1, size=(ub1-lb1)/N,
129
129
  ),
130
130
  y=dict(
131
- highlight=False, show=True, color='blue',
131
+ highlight=True, show=True, color='blue',
132
132
  start=lb2, end=ub2, size=(ub1-lb1)/N
133
133
  ),
134
134
  z=dict(highlight=False, show=False),
135
135
  )
136
- fig.add_trace(go.Surface(z=zz_mean, x=xx, y=yy, contours=contours))
136
+ fig.add_trace(
137
+ go.Surface(
138
+ z=zz_mean, x=xx, y=yy,
139
+ contours=contours,
140
+ showlegend=True,
141
+ name=Msg.LEGEND_LABEL_PREDICTION_MODEL,
142
+ colorbar=dict(
143
+ x=0.2,
144
+ xref="container",
145
+ # orientation='h',
146
+ )
147
+ )
148
+ )
137
149
  # std
138
- fig.add_trace(go.Surface(z=zz_upper, x=xx, y=yy, showscale=False, opacity=0.3))
139
- fig.add_trace(go.Surface(z=zz_lower, x=xx, y=yy, showscale=False, opacity=0.3))
150
+ fig.add_trace(go.Surface(z=zz_upper, x=xx, y=yy, showscale=False, opacity=0.3, showlegend=True, name=Msg.LEGEND_LABEL_PREDICTION_MODEL_STDDEV))
151
+ fig.add_trace(go.Surface(z=zz_lower, x=xx, y=yy, showscale=False, opacity=0.3, showlegend=True, name=Msg.LEGEND_LABEL_PREDICTION_MODEL_STDDEV))
140
152
 
141
153
  # layout
142
154
  fig.update_layout(
@@ -146,10 +158,9 @@ class PredictionModelCreator:
146
158
  yaxis_title=prm_name_2,
147
159
  zaxis_title=obj_name
148
160
  ),
149
- margin=dict(l=0, r=0, b=0, t=0),
161
+ margin=dict(l=0, r=0, b=0, t=30),
150
162
  )
151
163
 
152
-
153
164
  else:
154
165
  fig.add_trace(
155
166
  go.Scatter(x=xx, y=zz_mean, name=Msg.LEGEND_LABEL_PREDICTION_MODEL)