mg-pso-gui 0.1.40__py3-none-any.whl → 0.2.75__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/METADATA +10 -11
  2. mg_pso_gui-0.2.75.dist-info/RECORD +76 -0
  3. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/WHEEL +1 -1
  4. mgpsogui/gui/General/ParameterView.py +110 -0
  5. mgpsogui/gui/General/__init__.py +0 -0
  6. mgpsogui/gui/HomePage.py +234 -238
  7. mgpsogui/gui/OptionManager.py +333 -145
  8. mgpsogui/gui/OptionManager_backup.py +443 -0
  9. mgpsogui/gui/PlatformTab/PlatformTab.py +15 -6
  10. mgpsogui/gui/RunTab/OptimalParameterView.py +47 -0
  11. mgpsogui/gui/RunTab/RunTab.py +90 -17
  12. mgpsogui/gui/SetupTab/BoundsEditorWindow.py +1 -1
  13. mgpsogui/gui/SetupTab/BoundsList.py +97 -34
  14. mgpsogui/gui/SetupTab/CustomFunctionEditorWindow.py +74 -0
  15. mgpsogui/gui/SetupTab/CustomFunctionMetrics.py +156 -0
  16. mgpsogui/gui/SetupTab/FunctionsList.py +60 -6
  17. mgpsogui/gui/SetupTab/{StaticParameterView.py → ListEditor.py} +27 -16
  18. mgpsogui/gui/SetupTab/ListParametersView.py +7 -6
  19. mgpsogui/gui/SetupTab/{CalibrationParametersView.py → OverrideParameterMetrics.py} +35 -9
  20. mgpsogui/gui/SetupTab/OverrideParameterWindow.py +40 -0
  21. mgpsogui/gui/SetupTab/SetupTab.py +31 -11
  22. mgpsogui/gui/SetupTab/StepView.py +93 -22
  23. mgpsogui/gui/VisualizeTab/MatrixEditor.py +68 -0
  24. mgpsogui/gui/VisualizeTab/SideBar.py +316 -25
  25. mgpsogui/gui/VisualizeTab/VisualizeTab.py +69 -8
  26. mgpsogui/gui/defaults/__init__.py +0 -0
  27. mgpsogui/gui/defaults/optimization.json +176 -0
  28. mgpsogui/gui/defaults/sampling.json +111 -0
  29. mgpsogui/gui/defaults/sensitivity.json +20 -0
  30. mgpsogui/gui/images/plus.png +0 -0
  31. mgpsogui/util/GraphGenerator.py +721 -50
  32. mgpsogui/util/PSORunner.py +615 -86
  33. mgpsogui/util/debug.py +559 -0
  34. mgpsogui/util/helpers.py +95 -0
  35. mgpsogui/util/recosu/__init__.py +2 -1
  36. mgpsogui/util/recosu/pso/pso.py +55 -11
  37. mgpsogui/util/recosu/sampling/__init__.py +16 -0
  38. mgpsogui/util/recosu/sampling/halton/__init__.py +0 -0
  39. mgpsogui/util/recosu/sampling/halton/halton.py +45 -0
  40. mgpsogui/util/recosu/sampling/halton/prime.py +82 -0
  41. mgpsogui/util/recosu/sampling/random/__init__.py +0 -0
  42. mgpsogui/util/recosu/sampling/random/random_sampler.py +34 -0
  43. mgpsogui/util/recosu/sampling/sample_trace_writer.py +47 -0
  44. mgpsogui/util/recosu/sampling/sampler_task.py +75 -0
  45. mgpsogui/util/recosu/sampling/sampling.py +99 -0
  46. mgpsogui/util/sampler_test_driver.py +129 -0
  47. mg_pso_gui-0.1.40.dist-info/RECORD +0 -52
  48. mgpsogui/gui/images/IGOW 4 Logo.png +0 -0
  49. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/entry_points.txt +0 -0
  50. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/top_level.txt +0 -0
@@ -1,31 +1,100 @@
1
1
  import plotly.express as px
2
2
  import plotly.graph_objs as go
3
+ from plotly.subplots import make_subplots
3
4
  import pandas as pd
4
5
  import numpy as np
5
6
  import os
6
7
  from PIL import Image, ImageTk
7
8
  import customtkinter
9
+ import traceback
10
+ import math
11
+
12
+ baseFigureWidth = 700
13
+ baseFigureHeight = 350
14
+
15
+ theme_background_color = {
16
+ "Dark": 'rgba(42, 42, 42, 0)',
17
+ "Light": 'rgba(255, 255, 255, 0)',
18
+ "Publication": 'rgba(255, 255, 255, 0)'
19
+ }
20
+
21
+ theme_background_color_html = {
22
+ "Dark": '#2a2a2a',
23
+ "Light": '#ffffff',
24
+ "Publication": '#ffffff'
25
+ }
26
+
27
+ theme_plot_color = {
28
+ "Dark": 'rgb(62, 62, 62)',
29
+ "Light": 'rgba(245,245,255,255)',
30
+ "Publication": 'rgba(245,245,255,255)'
31
+ }
32
+
33
+ theme_grid_color = {
34
+ "Dark": 'rgb(72, 72, 72)',
35
+ "Light": 'rgb(255, 255, 255)',
36
+ "Publication": 'rgb(255, 255, 255)'
37
+ }
38
+
39
+ theme_line_color = {
40
+ "Dark": 'rgb(102, 102, 102)',
41
+ "Light": 'rgb(102, 102, 102)',
42
+ "Publication": 'rgb(102, 102, 102)'
43
+ }
44
+
45
+ theme_font_color = {
46
+ "Dark": 'white',
47
+ "Light": 'black',
48
+ "Publication": 'black'
49
+ }
50
+
51
+ theme_plot_color_pallet = [
52
+ "rgba(151, 209, 233, 255)",
53
+ "rgba(0, 120, 179, 255)",
54
+ "rgba(179, 223, 146, 255)",
55
+ "rgba(49, 169, 90, 255)",
56
+ "rgba(227, 136, 220, 255)",
57
+ "rgba(127, 0, 255, 255)",
58
+ "rgba(255, 128, 0, 255)",
59
+ "rgba(255, 99, 71, 255)",
60
+ "rgba(102, 205, 170, 255)",
61
+ "rgba(255, 215, 0, 255)",
62
+ "rgba(70, 130, 180, 255)"
63
+ ]
8
64
 
9
65
  def generate_graphs(HomePage):
66
+
10
67
  try:
11
- selected_graph = HomePage.graph_selector_value.get()
12
- info = HomePage.option_manager.get_project_data()
13
- folder = os.path.join(info['path'], info['name'])
68
+ selected_graph = HomePage.option_manager.get("selected_graph").get()
69
+ folder = HomePage.option_manager.get_project_folder()
14
70
  if not os.path.exists(folder):
15
71
  os.makedirs(folder)
16
72
 
17
73
  if (selected_graph == "Best Cost Stacked"):
18
74
  HomePage.selected_graph_name = "best_cost_stacked"
19
- best_cost_stacked(HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
75
+ best_cost_stacked(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
20
76
  elif (selected_graph == "Best Cost by Round"):
21
77
  HomePage.selected_graph_name = "best_cost_by_round"
22
- best_cost_by_round(HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
78
+ best_cost_by_round(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
23
79
  elif (selected_graph == "Iteration Table"):
24
80
  HomePage.selected_graph_name = "table"
25
- table(HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
81
+ table(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
26
82
  elif (selected_graph == "Calibrated Parameters"):
27
83
  HomePage.selected_graph_name = "calibrated_params_by_round"
28
- calibrated_params_by_round(HomePage.running_config['steps'], HomePage.calibration_data, HomePage.option_manager)
84
+ calibrated_params_by_round(HomePage, HomePage.running_config['steps'], HomePage.calibration_data, HomePage.option_manager)
85
+ elif (selected_graph == "Custom CSV"):
86
+ HomePage.selected_graph_name = "custom_csv"
87
+ custom_csv(HomePage, HomePage.option_manager)
88
+ elif (selected_graph == "Compare CSV"):
89
+ HomePage.selected_graph_name = "compare_csv"
90
+ compare_csv(HomePage, HomePage.option_manager)
91
+ elif (selected_graph == "Sampling CSV"):
92
+ HomePage.selected_graph_name = "sampling_csv"
93
+ sampling_csv(HomePage, HomePage.option_manager)
94
+ elif (selected_graph == "Matrix Editor"):
95
+ HomePage.selected_graph_name = "matrix_editor"
96
+ matrix_editor(HomePage, HomePage.option_manager)
97
+ pass
29
98
 
30
99
  image_path = os.path.join(folder, HomePage.selected_graph_name + ".png")
31
100
 
@@ -36,41 +105,62 @@ def generate_graphs(HomePage):
36
105
  HomePage.graph_image = customtkinter.CTkImage(HomePage.graph_image_obj, size=(HomePage.image_width * HomePage.image_scale, HomePage.image_height * HomePage.image_scale))
37
106
  HomePage.graph_label.configure(image=HomePage.graph_image)
38
107
  except Exception as e:
39
- pass
108
+ print(f"An exception occurred in Graph Generator: {str(e)}")
109
+ print(f"Exception type: {type(e).__name__}")
110
+ print("Traceback:")
111
+ traceback.print_exc()
112
+
113
+ def best_cost_stacked(homepage, config, data, option_manager):
114
+ theme = homepage.option_manager.get("graph_theme").get()
40
115
 
41
- def best_cost_stacked(config, dataframe, option_manager):
42
116
  fig = go.Figure()
43
117
 
44
118
  total_steps = len(config)
45
119
 
46
120
  # Get unique values from the round_step column of the dataframe
47
- for iteration in dataframe['round_step'].unique():
48
- # Get best_cost and completed rounds rows for this iteration
49
- df = dataframe[dataframe['round_step'] == iteration]
50
-
51
- step_index = ((iteration) % total_steps)
52
- round_index = ((iteration) // total_steps)
53
-
54
- fig.add_trace(go.Scatter(x=df['completed_rounds'], y=df['best_cost'], name='Round ' + str(round_index + 1) + ' Group ' + str(step_index + 1)))
121
+ pp = 0
122
+ for round_step in data.keys():
123
+ fig.add_trace(go.Scatter(x=data[round_step]["percent"], y=data[round_step]["best_cost"], name=round_step, marker_color=theme_plot_color_pallet[pp]))
124
+ pp += 1
55
125
 
56
126
  fig.update_layout(
57
127
  title="",
58
- xaxis_title="Iteration",
128
+ xaxis_title="Progress (% through Group)",
59
129
  yaxis_title="Best Cost",
60
- font=dict(color='white'),
61
- paper_bgcolor='rgba(42, 42, 42, 0)',
62
- plot_bgcolor='rgb(62, 62, 62)',
130
+ font=dict(color=theme_font_color[theme]),
131
+ paper_bgcolor=theme_background_color[theme],
132
+ plot_bgcolor=theme_plot_color[theme],
63
133
  xaxis=dict(
64
- gridcolor='rgb(72, 72, 72)',
134
+ gridcolor=theme_grid_color[theme],
65
135
  gridwidth=1
66
136
  ),
67
137
  yaxis=dict(
68
138
  range=[0, 0.6],
69
139
  autorange=True,
70
- gridcolor='rgb(72, 72, 72)',
140
+ gridcolor=theme_grid_color[theme],
71
141
  gridwidth=0.1
72
142
  )
73
143
  )
144
+ if (theme == "Publication"):
145
+ fig.update_layout(
146
+ font=dict(
147
+ size=16
148
+ ),
149
+ legend=dict(
150
+ orientation="h",
151
+ yanchor="bottom",
152
+ y=1.02,
153
+ xanchor="center",
154
+ x=0.47
155
+ ),
156
+ margin=dict(
157
+ t=0,
158
+ b=1,
159
+ l=1,
160
+ r=1,
161
+ autoexpand=True
162
+ )
163
+ )
74
164
 
75
165
  info = option_manager.get_project_data()
76
166
  folder = os.path.join(info['path'], info['name'])
@@ -80,6 +170,8 @@ def best_cost_stacked(config, dataframe, option_manager):
80
170
 
81
171
  fig.write_image(os.path.join(folder, "best_cost_stacked.png"), width=1280, height=720)
82
172
  fig.write_html(os.path.join(folder, "best_cost_stacked.html"), include_plotlyjs='cdn', auto_open=False)
173
+ fig.write_json(os.path.join(folder, "best_cost_stacked.json"))
174
+ fig.write_image(os.path.join(folder, "best_cost_stacked.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
83
175
  with open(os.path.join(folder, "best_cost_stacked.html"), "r") as f:
84
176
  html = f.read()
85
177
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -89,7 +181,9 @@ def best_cost_stacked(config, dataframe, option_manager):
89
181
 
90
182
  return fig
91
183
 
92
- def table(config, dataframe, option_manager):
184
+ def table(homepage, config, dataframe, option_manager):
185
+ theme = homepage.option_manager.get("graph_theme").get()
186
+
93
187
  # Create a plotly table with the values in the dataframe
94
188
  fig = go.Figure(data=[go.Table(
95
189
  header=dict(
@@ -107,20 +201,40 @@ def table(config, dataframe, option_manager):
107
201
  title="",
108
202
  xaxis_title="Iteration",
109
203
  yaxis_title="Best Cost",
110
- font=dict(color='white'),
111
- paper_bgcolor='rgba(42, 42, 42, 0)',
112
- plot_bgcolor='rgb(62, 62, 62)',
204
+ font=dict(color=theme_font_color[theme]),
205
+ paper_bgcolor=theme_background_color[theme],
206
+ plot_bgcolor=theme_plot_color[theme],
113
207
  xaxis=dict(
114
- gridcolor='rgb(72, 72, 72)',
208
+ gridcolor=theme_grid_color[theme],
115
209
  gridwidth=1
116
210
  ),
117
211
  yaxis=dict(
118
212
  range=[0, 0.6],
119
213
  autorange=True,
120
- gridcolor='rgb(72, 72, 72)',
214
+ gridcolor=theme_grid_color[theme],
121
215
  gridwidth=0.1
122
216
  )
123
217
  )
218
+ if (theme == "Publication"):
219
+ fig.update_layout(
220
+ font=dict(
221
+ size=16
222
+ ),
223
+ legend=dict(
224
+ orientation="h",
225
+ yanchor="bottom",
226
+ y=1.02,
227
+ xanchor="center",
228
+ x=0.47
229
+ ),
230
+ margin=dict(
231
+ t=0,
232
+ b=1,
233
+ l=1,
234
+ r=1,
235
+ autoexpand=True
236
+ )
237
+ )
124
238
 
125
239
  info = option_manager.get_project_data()
126
240
  folder = os.path.join(info['path'], info['name'])
@@ -130,6 +244,8 @@ def table(config, dataframe, option_manager):
130
244
 
131
245
  fig.write_image(os.path.join(folder, "table.png"), width=1280, height=720)
132
246
  fig.write_html(os.path.join(folder, "table.html"), include_plotlyjs='cdn', auto_open=False)
247
+ fig.write_json(os.path.join(folder, "table.json"))
248
+ fig.write_image(os.path.join(folder, "table.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
133
249
  with open(os.path.join(folder, "table.html"), "r") as f:
134
250
  html = f.read()
135
251
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -138,22 +254,33 @@ def table(config, dataframe, option_manager):
138
254
 
139
255
  return fig
140
256
 
141
- def best_cost_by_round(config, dataframe, option_manager):
257
+ def best_cost_by_round(homepage, config, data, option_manager):
258
+ theme = homepage.option_manager.get("graph_theme").get()
259
+
142
260
  fig = go.Figure()
143
261
 
144
262
  total_steps = len(config)
145
263
 
264
+ pp = 0
146
265
  # Get unique values from the round_step column of the dataframe
147
- for iteration in dataframe['round_step'].unique():
266
+ for round_step in data.keys():
267
+ #for iteration in dataframe['round_step'].unique():
148
268
  # Get best_cost and completed rounds rows for this iteration
149
- df = dataframe[dataframe['round_step'] == iteration]
269
+
270
+ round_index = int(round_step.split(" -")[0].replace("Round: ", "")) - 1
271
+
272
+ #df = dataframe[dataframe['round_step'] == iteration]
150
273
 
151
- step_index = ((iteration) % total_steps)
152
- round_index = ((iteration) // total_steps)
274
+ #step_index = ((iteration) % total_steps)
275
+ #round_index = ((iteration) // total_steps)
276
+
277
+ fig.add_trace(go.Scatter(x=np.array(data[round_step]['percent']) + (100 * round_index), y=data[round_step]['best_cost'], name=round_step, marker_color=theme_plot_color_pallet[pp]))
278
+ pp += 1
279
+
280
+ #fig.add_trace(go.Scatter(x=df['completed_rounds'] + (df['total_rounds'] * round_index), y=df['best_cost'], name='Group ' + str(step_index + 1)))
153
281
 
154
- fig.add_trace(go.Scatter(x=df['completed_rounds'] + (df['total_rounds'] * round_index), y=df['best_cost'], name='Group ' + str(step_index + 1)))
155
282
 
156
- xx = np.max(df['completed_rounds']) + (np.max(df['total_rounds']) * round_index)
283
+ xx = np.max(np.array(data[round_step]["percent"]) + (100 * round_index))
157
284
  fig.add_shape(
158
285
  type='line',
159
286
  x0=xx,
@@ -162,7 +289,7 @@ def best_cost_by_round(config, dataframe, option_manager):
162
289
  y1=1,
163
290
  yref='paper',
164
291
  line=dict(
165
- color='rgb(102, 102, 102)',
292
+ color=theme_line_color[theme],
166
293
  width=2
167
294
  )
168
295
  )
@@ -178,22 +305,42 @@ def best_cost_by_round(config, dataframe, option_manager):
178
305
 
179
306
  fig.update_layout(
180
307
  title="",
181
- xaxis_title="Iteration",
308
+ xaxis_title="Progress (%)",
182
309
  yaxis_title="Best Cost",
183
- font=dict(color='white'),
184
- paper_bgcolor='rgba(42, 42, 42, 0)',
185
- plot_bgcolor='rgb(62, 62, 62)',
310
+ font=dict(color=theme_font_color[theme]),
311
+ paper_bgcolor=theme_background_color[theme],
312
+ plot_bgcolor=theme_plot_color[theme],
186
313
  xaxis=dict(
187
- gridcolor='rgb(72, 72, 72)',
314
+ gridcolor=theme_grid_color[theme],
188
315
  gridwidth=1
189
316
  ),
190
317
  yaxis=dict(
191
318
  range=[0, 0.6],
192
319
  autorange=True,
193
- gridcolor='rgb(72, 72, 72)',
320
+ gridcolor=theme_grid_color[theme],
194
321
  gridwidth=0.1
195
322
  )
196
323
  )
324
+ if (theme == "Publication"):
325
+ fig.update_layout(
326
+ font=dict(
327
+ size=16
328
+ ),
329
+ legend=dict(
330
+ orientation="h",
331
+ yanchor="bottom",
332
+ y=1.02,
333
+ xanchor="center",
334
+ x=0.47
335
+ ),
336
+ margin=dict(
337
+ t=0,
338
+ b=1,
339
+ l=1,
340
+ r=1,
341
+ autoexpand=True
342
+ )
343
+ )
197
344
 
198
345
  info = option_manager.get_project_data()
199
346
  folder = os.path.join(info['path'], info['name'])
@@ -203,6 +350,8 @@ def best_cost_by_round(config, dataframe, option_manager):
203
350
 
204
351
  fig.write_image(os.path.join(folder, "best_cost_by_round.png"), width=1280, height=720)
205
352
  fig.write_html(os.path.join(folder, "best_cost_by_round.html"), include_plotlyjs='cdn', auto_open=False)
353
+ fig.write_json(os.path.join(folder, "best_cost_by_round.json"))
354
+ fig.write_image(os.path.join(folder, "best_cost_by_round.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
206
355
  with open(os.path.join(folder, "best_cost_by_round.html"), "r") as f:
207
356
  html = f.read()
208
357
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -211,7 +360,9 @@ def best_cost_by_round(config, dataframe, option_manager):
211
360
 
212
361
  return fig
213
362
 
214
- def calibrated_params_by_round(config, list_of_objs, option_manager):
363
+ def calibrated_params_by_round(homepage, config, list_of_objs, option_manager):
364
+ theme = homepage.option_manager.get("graph_theme").get()
365
+
215
366
  fig = go.Figure()
216
367
 
217
368
  total_steps = len(config)
@@ -234,29 +385,51 @@ def calibrated_params_by_round(config, list_of_objs, option_manager):
234
385
  round += 1
235
386
 
236
387
  # Get unique values from the round_step column of the dataframe
388
+ pp = 0
237
389
  for key in datalines.keys():
238
390
  # Get best_cost and completed rounds rows for this iteration
239
391
  if key == 'step' or key == 'round':
240
392
  continue
241
393
 
242
- fig.add_trace(go.Scatter(x=datalines['round'], y=datalines[key], name=key))
394
+ fig.add_trace(go.Scatter(x=datalines['round'], y=datalines[key], name=key, marker_color=theme_plot_color_pallet[pp]))
395
+ pp += 1
243
396
 
244
397
  fig.update_layout(
245
398
  title="",
246
399
  xaxis_title="Round",
247
400
  yaxis_title="Particle Parameters",
248
- font=dict(color='white'),
249
- paper_bgcolor='rgba(42, 42, 42, 0)',
250
- plot_bgcolor='rgb(62, 62, 62)',
401
+ font=dict(color=theme_font_color[theme]),
402
+ paper_bgcolor=theme_background_color[theme],
403
+ plot_bgcolor=theme_plot_color[theme],
251
404
  xaxis=dict(
252
- gridcolor='rgb(72, 72, 72)',
405
+ gridcolor=theme_grid_color[theme],
253
406
  gridwidth=1
254
407
  ),
255
408
  yaxis=dict(
256
- gridcolor='rgb(72, 72, 72)',
409
+ gridcolor=theme_grid_color[theme],
257
410
  gridwidth=0.1
258
411
  )
259
412
  )
413
+ if (theme == "Publication"):
414
+ fig.update_layout(
415
+ font=dict(
416
+ size=16
417
+ ),
418
+ legend=dict(
419
+ orientation="h",
420
+ yanchor="bottom",
421
+ y=1.02,
422
+ xanchor="center",
423
+ x=0.47
424
+ ),
425
+ margin=dict(
426
+ t=0,
427
+ b=1,
428
+ l=1,
429
+ r=1,
430
+ autoexpand=True
431
+ )
432
+ )
260
433
 
261
434
  info = option_manager.get_project_data()
262
435
  folder = os.path.join(info['path'], info['name'])
@@ -266,10 +439,508 @@ def calibrated_params_by_round(config, list_of_objs, option_manager):
266
439
 
267
440
  fig.write_image(os.path.join(folder, "calibrated_params_by_round.png"), width=1280, height=720)
268
441
  fig.write_html(os.path.join(folder, "calibrated_params_by_round.html"), include_plotlyjs='cdn', auto_open=False)
442
+ fig.write_json(os.path.join(folder, "calibrated_params_by_round.json"))
443
+ fig.write_image(os.path.join(folder, "calibrated_params_by_round.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
269
444
  with open(os.path.join(folder, "calibrated_params_by_round.html"), "r") as f:
270
445
  html = f.read()
271
446
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
272
447
  with open(os.path.join(folder, "calibrated_params_by_round.html"), "w") as f:
273
448
  f.write(html)
274
449
 
450
+ return fig
451
+
452
+ def custom_csv(homepage, option_manager):
453
+ theme = homepage.option_manager.get("graph_theme").get()
454
+
455
+ fig = go.Figure()
456
+
457
+ data = homepage.csv_data["data"]
458
+
459
+ x = option_manager.get("selected_x").get()
460
+ val = option_manager.get("selected_y1").get()
461
+ val2 = option_manager.get("selected_y2").get()
462
+
463
+ xx = None
464
+ if x == "time":
465
+ xx = pd.to_datetime(data["time"], format='%Y-%m-%d', errors='coerce')
466
+ elif x == "date":
467
+ xx = pd.to_datetime(data["date"], format='%d-%m-%Y', errors='coerce')
468
+ else:
469
+ xx = pd.to_numeric(data[x], errors="coerce")
470
+
471
+ yy = pd.to_numeric(data[val], errors="coerce")
472
+
473
+ yy_unit = "-"
474
+ if "Unit" in homepage.csv_data["data_attributes"]:
475
+ yy_unit = homepage.csv_data["data_attributes"]["Unit"][val]
476
+
477
+ yy2 = pd.to_numeric(data[val2], errors="coerce")
478
+
479
+ yy2_unit = "-"
480
+ if "Unit" in homepage.csv_data["data_attributes"]:
481
+ yy2_unit = homepage.csv_data["data_attributes"]["Unit"][val2]
482
+
483
+ fig.add_trace(go.Scatter(x=xx, y=yy, name=val, marker_color=theme_plot_color_pallet[1]))
484
+ fig.add_trace(go.Scatter(x=xx, y=yy2, name=val2, yaxis='y2', marker_color=theme_plot_color_pallet[3]))
485
+
486
+ fig.update_layout(
487
+ title="",
488
+ xaxis_title=x,
489
+ yaxis_title=val,
490
+ font=dict(color=theme_font_color[theme]),
491
+ paper_bgcolor=theme_background_color[theme],
492
+ plot_bgcolor=theme_plot_color[theme],
493
+ xaxis=dict(
494
+ gridcolor=theme_grid_color[theme],
495
+ gridwidth=1
496
+ ),
497
+ yaxis=dict(
498
+ title=val + " (" + str(yy_unit) + ")",
499
+ autorange=True,
500
+ gridcolor=theme_grid_color[theme],
501
+ gridwidth=0.1
502
+ ),
503
+ yaxis2=dict(
504
+ title=val2 + " (" + str(yy2_unit) + ")",
505
+ overlaying='y',
506
+ side='right'
507
+ )
508
+ )
509
+ if (theme == "Publication"):
510
+ fig.update_layout(
511
+ font=dict(
512
+ size=16
513
+ ),
514
+ legend=dict(
515
+ orientation="h",
516
+ yanchor="bottom",
517
+ y=1.02,
518
+ xanchor="center",
519
+ x=0.47
520
+ ),
521
+ margin=dict(
522
+ t=0,
523
+ b=1,
524
+ l=1,
525
+ r=1,
526
+ autoexpand=True
527
+ )
528
+ )
529
+
530
+ info = option_manager.get_project_data()
531
+ folder = os.path.join(info['path'], info['name'])
532
+
533
+ if not os.path.exists(folder):
534
+ os.makedirs(folder)
535
+
536
+ fig.write_image(os.path.join(folder, "custom_csv.png"), width=1280, height=720)
537
+ fig.write_html(os.path.join(folder, "custom_csv.html"), include_plotlyjs='cdn', auto_open=False)
538
+ fig.write_json(os.path.join(folder, "custom_csv.json"))
539
+ fig.write_image(os.path.join(folder, "custom_csv.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
540
+ with open(os.path.join(folder, "custom_csv.html"), "r") as f:
541
+ html = f.read()
542
+ html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
543
+ with open(os.path.join(folder, "custom_csv.html"), "w") as f:
544
+ f.write(html)
545
+
546
+ return fig
547
+
548
+ def compare_csv(homepage, option_manager):
549
+ theme = homepage.option_manager.get("graph_theme").get()
550
+
551
+ fig = go.Figure()
552
+
553
+ data = homepage.csv_data["data"]
554
+ data2 = homepage.csv_data2["data"]
555
+
556
+ x = option_manager.get("selected_x").get()
557
+ val = option_manager.get("selected_y1").get()
558
+ val2 = option_manager.get("selected_y2").get()
559
+
560
+ xx = None
561
+ if x == "time":
562
+ xx = pd.to_datetime(data["time"], format='%Y-%m-%d', errors='coerce')
563
+ elif x == "date":
564
+ xx = pd.to_datetime(data["date"], format='%d-%m-%Y', errors='coerce')
565
+ else:
566
+ xx = pd.to_numeric(data[x], errors="coerce")
567
+
568
+ yy = pd.to_numeric(data[val], errors="coerce")
569
+
570
+ xx2 = None
571
+ if x == "time":
572
+ xx2 = pd.to_datetime(data2["time"], format='%Y-%m-%d', errors='coerce')
573
+ elif x == "date":
574
+ xx2 = pd.to_datetime(data2["date"], format='%d-%m-%Y', errors='coerce')
575
+ else:
576
+ xx2 = pd.to_numeric(data2[x], errors="coerce")
577
+
578
+ yy_unit = "-"
579
+ if "Unit" in homepage.csv_data["data_attributes"]:
580
+ yy_unit = homepage.csv_data["data_attributes"]["Unit"][val]
581
+
582
+ yy2 = pd.to_numeric(data[val2], errors="coerce")
583
+
584
+ yy2_unit = "-"
585
+ if "Unit" in homepage.csv_data["data_attributes"]:
586
+ yy2_unit = homepage.csv_data["data_attributes"]["Unit"][val2]
587
+
588
+ fig.add_trace(go.Scatter(x=xx, y=yy, name=val, marker_color=theme_plot_color_pallet[1]))
589
+ fig.add_trace(go.Scatter(x=xx2, y=yy2, name=val2, yaxis='y2', marker_color=theme_plot_color_pallet[3]))
590
+
591
+ fig.update_layout(
592
+ title="",
593
+ xaxis_title=x,
594
+ yaxis_title=val,
595
+ font=dict(color=theme_font_color[theme]),
596
+ paper_bgcolor=theme_background_color[theme],
597
+ plot_bgcolor=theme_plot_color[theme],
598
+ xaxis=dict(
599
+ gridcolor=theme_grid_color[theme],
600
+ gridwidth=1
601
+ ),
602
+ yaxis=dict(
603
+ title=val + " (" + str(yy_unit) + ")",
604
+ autorange=True,
605
+ gridcolor=theme_grid_color[theme],
606
+ gridwidth=0.1
607
+ ),
608
+ yaxis2=dict(
609
+ title=val2 + " (" + str(yy2_unit) + ")",
610
+ overlaying='y',
611
+ side='right'
612
+ )
613
+ )
614
+ if (theme == "Publication"):
615
+ fig.update_layout(
616
+ font=dict(
617
+ size=16
618
+ ),
619
+ legend=dict(
620
+ orientation="h",
621
+ yanchor="bottom",
622
+ y=1.02,
623
+ xanchor="center",
624
+ x=0.47
625
+ ),
626
+ margin=dict(
627
+ t=0,
628
+ b=1,
629
+ l=1,
630
+ r=1,
631
+ autoexpand=True
632
+ )
633
+ )
634
+
635
+ info = option_manager.get_project_data()
636
+ folder = os.path.join(info['path'], info['name'])
637
+
638
+ if not os.path.exists(folder):
639
+ os.makedirs(folder)
640
+
641
+ fig.write_image(os.path.join(folder, "compare_csv.png"), width=1280, height=720)
642
+ fig.write_html(os.path.join(folder, "compare_csv.html"), include_plotlyjs='cdn', auto_open=False)
643
+ fig.write_json(os.path.join(folder, "compare_csv.json"))
644
+ fig.write_image(os.path.join(folder, "compare_csv.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
645
+ with open(os.path.join(folder, "compare_csv.html"), "r") as f:
646
+ html = f.read()
647
+ html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
648
+ with open(os.path.join(folder, "compare_csv.html"), "w") as f:
649
+ f.write(html)
650
+
651
+ return fig
652
+
653
+ def sampling_csv(homepage, option_manager):
654
+ theme = homepage.option_manager.get("graph_theme").get()
655
+
656
+ fig = go.Figure()
657
+
658
+ style = option_manager.get("figure_style").get()
659
+
660
+ data = homepage.csv_data
661
+
662
+ x = option_manager.get("selected_x").get()
663
+ val = option_manager.get("selected_y1").get()
664
+ val2 = option_manager.get("selected_y2").get()
665
+
666
+ xx = None
667
+ if x == "time":
668
+ xx = pd.to_datetime(data["time"], format='%Y-%m-%d', errors='coerce')
669
+ elif x == "date":
670
+ xx = pd.to_datetime(data["date"], format='%d-%m-%Y', errors='coerce')
671
+ else:
672
+ xx = pd.to_numeric(data[x], errors="coerce")
673
+
674
+ yy = pd.to_numeric(data[val], errors="coerce")
675
+
676
+ yy_unit = ""
677
+
678
+ yy2 = pd.to_numeric(data[val2], errors="coerce")
679
+
680
+ yy2_unit = ""
681
+
682
+ if (style == "Scatter"):
683
+ fig.add_trace(go.Scatter(x=xx, y=yy, name=val, mode='markers', marker_color=theme_plot_color_pallet[1]))
684
+ fig.add_trace(go.Scatter(x=xx, y=yy2, name=val2, yaxis='y2', mode='markers', marker_color=theme_plot_color_pallet[3]))
685
+ elif (style == "Bars"):
686
+ fig.add_trace(go.Bar(x=xx, y=yy, name=val, marker_color=theme_plot_color_pallet[1]))
687
+ fig.add_trace(go.Bar(x=xx, y=yy2, name=val2, yaxis='y2', marker_color=theme_plot_color_pallet[3]))
688
+ elif (style == "Lines"):
689
+ fig.add_trace(go.Scatter(x=xx, y=yy, name=val, marker_color=theme_plot_color_pallet[1]))
690
+ fig.add_trace(go.Scatter(x=xx, y=yy2, name=val2, yaxis='y2', marker_color=theme_plot_color_pallet[3]))
691
+ elif (style == "Area"):
692
+ fig.add_trace(go.Scatter(x=xx, y=yy, name=val, fill='tozeroy', marker_color=theme_plot_color_pallet[1]))
693
+ fig.add_trace(go.Scatter(x=xx, y=yy2, name=val2, yaxis='y2', fill='tozeroy', marker_color=theme_plot_color_pallet[3]))
694
+ elif (style == "Box"):
695
+ fig.add_trace(go.Box(x=xx, y=yy, name=val, marker_color=theme_plot_color_pallet[1]))
696
+ fig.add_trace(go.Box(x=xx, y=yy2, name=val2, yaxis='y2', marker_color=theme_plot_color_pallet[3]))
697
+
698
+ fig.update_layout(
699
+ title="",
700
+ xaxis_title=x,
701
+ yaxis_title=val,
702
+ font=dict(color=theme_font_color[theme]),
703
+ paper_bgcolor=theme_background_color[theme],
704
+ plot_bgcolor=theme_plot_color[theme],
705
+ xaxis=dict(
706
+ gridcolor=theme_grid_color[theme],
707
+ gridwidth=1
708
+ ),
709
+ yaxis=dict(
710
+ title=val,
711
+ autorange=True,
712
+ gridcolor=theme_grid_color[theme],
713
+ gridwidth=0.1
714
+ ),
715
+ yaxis2=dict(
716
+ title=val2,
717
+ overlaying='y',
718
+ side='right'
719
+ )
720
+ )
721
+ if (theme == "Publication"):
722
+ fig.update_layout(
723
+ font=dict(
724
+ size=16
725
+ ),
726
+ legend=dict(
727
+ orientation="h",
728
+ yanchor="bottom",
729
+ y=1.02,
730
+ xanchor="center",
731
+ x=0.47
732
+ ),
733
+ margin=dict(
734
+ t=0,
735
+ b=1,
736
+ l=1,
737
+ r=1,
738
+ autoexpand=True
739
+ )
740
+ )
741
+
742
+ info = option_manager.get_project_data()
743
+ folder = os.path.join(info['path'], info['name'])
744
+
745
+ if not os.path.exists(folder):
746
+ os.makedirs(folder)
747
+
748
+ fig.write_image(os.path.join(folder, "sampling_csv.png"), width=1280, height=720)
749
+ fig.write_html(os.path.join(folder, "sampling_csv.html"), include_plotlyjs='cdn', auto_open=False)
750
+ fig.write_json(os.path.join(folder, "sampling_csv.json"))
751
+ fig.write_image(os.path.join(folder, "sampling_csv.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
752
+ with open(os.path.join(folder, "sampling_csv.html"), "r") as f:
753
+ html = f.read()
754
+ html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
755
+ with open(os.path.join(folder, "sampling_csv.html"), "w") as f:
756
+ f.write(html)
757
+
758
+ return fig
759
+
760
+ def matrix_editor(homepage, option_manager):
761
+ theme = homepage.option_manager.get("graph_theme").get()
762
+
763
+ style = option_manager.get("figure_style").get()
764
+ data = homepage.csv_data
765
+ x = option_manager.get("selected_x").get()
766
+
767
+ all_figures = []
768
+ figure_parameters = option_manager.get('figure_parameters')
769
+
770
+ #color_list = ['#636EFA', '#EF553B', '#00CC96', '#AB63FA', '#FFA15A', '#19D3F3', '#FF6692', '#B6E880', '#FF97FF', '#FECB52']
771
+ color_index = 0
772
+ color_dict = {}
773
+
774
+ total_figures = 0
775
+ for parameter in figure_parameters:
776
+ name = parameter['name'].get()
777
+ if ("Fig" not in name):
778
+ continue
779
+ total_figures += 1
780
+
781
+ figures_per_row = 1
782
+ if (total_figures == 1):
783
+ figures_per_row = 1
784
+ elif (total_figures == 2):
785
+ figures_per_row = 2
786
+ elif (total_figures == 3 or total_figures == 4):
787
+ figures_per_row = 2
788
+ elif (total_figures == 5 or total_figures == 6):
789
+ figures_per_row = 3
790
+ elif (total_figures == 7 or total_figures == 8):
791
+ figures_per_row = 4
792
+ elif (total_figures == 9):
793
+ figures_per_row = 3
794
+ else:
795
+ figures_per_row = 4
796
+
797
+ fig_combined = make_subplots(rows=(math.ceil(total_figures / figures_per_row)), cols=figures_per_row, shared_xaxes=False, shared_yaxes=False)
798
+
799
+ pp = 0
800
+ for parameter in figure_parameters:
801
+ name = parameter['name'].get()
802
+
803
+ if ("Fig" not in name):
804
+ continue
805
+
806
+ fig = go.Figure()
807
+ val = parameter['value'].get()
808
+
809
+ xx = None
810
+ #if x == "time":
811
+ # xx = pd.to_datetime(data["time"], format='%Y-%m-%d', errors='coerce')
812
+ #elif x == "date":
813
+ # xx = pd.to_datetime(data["date"], format='%d-%m-%Y', errors='coerce')
814
+ #else:
815
+ xx = pd.to_numeric(data[x], errors="coerce")
816
+ yy = pd.to_numeric(data[val], errors="coerce")
817
+
818
+ yy_unit = ""
819
+
820
+ if (style == "Scatter"):
821
+ fig.add_trace(go.Scatter(x=yy, y=xx, name=val, mode='markers', marker_color=theme_plot_color_pallet[pp]))
822
+ elif (style == "Bars"):
823
+ fig.add_trace(go.Bar(x=yy, y=xx, name=val, marker_color=theme_plot_color_pallet[pp]))
824
+ elif (style == "Lines"):
825
+ fig.add_trace(go.Scatter(x=yy, y=xx, name=val, marker_color=theme_plot_color_pallet[pp]))
826
+ elif (style == "Area"):
827
+ fig.add_trace(go.Scatter(x=yy, y=xx, name=val, fill='tozeroy', marker_color=theme_plot_color_pallet[pp]))
828
+ elif (style == "Box"):
829
+ fig.add_trace(go.Box(x=yy, y=xx, name=val, marker_color=theme_plot_color_pallet[pp]))
830
+
831
+ pp += 1
832
+
833
+ fig.update_layout(
834
+ title="",
835
+ xaxis_title=val,
836
+ yaxis_title=x,
837
+ font=dict(color=theme_font_color[theme]),
838
+ paper_bgcolor=theme_background_color[theme],
839
+ plot_bgcolor=theme_plot_color[theme],
840
+ xaxis=dict(
841
+ gridcolor=theme_grid_color[theme],
842
+ gridwidth=1
843
+ ),
844
+ yaxis=dict(
845
+ title=x,
846
+ autorange=True,
847
+ gridcolor=theme_grid_color[theme],
848
+ gridwidth=0.1
849
+ )
850
+ )
851
+ if (theme == "Publication"):
852
+ fig.update_layout(
853
+ font=dict(
854
+ size=16
855
+ ),
856
+ legend=dict(
857
+ orientation="h",
858
+ yanchor="bottom",
859
+ y=1.02,
860
+ xanchor="center",
861
+ x=0.47
862
+ ),
863
+ margin=dict(
864
+ t=0,
865
+ b=1,
866
+ l=1,
867
+ r=1,
868
+ autoexpand=True
869
+ )
870
+ )
871
+
872
+ all_figures.append(fig)
873
+
874
+ row = 1
875
+ col = 1
876
+ for fig in all_figures:
877
+ for trace in fig.data:
878
+
879
+ if trace.name not in color_dict:
880
+ color_dict[trace.name] = theme_plot_color_pallet[color_index % len(theme_plot_color_pallet)]
881
+ color_index += 1
882
+
883
+ trace.marker.color = color_dict[trace.name]
884
+
885
+ if fig_combined.data:
886
+ trace.showlegend = not any(t.name == trace.name for t in fig_combined.data)
887
+ fig_combined.add_trace(trace, row=row, col=col)
888
+
889
+ # Get the layout titles from the individual figure
890
+ xaxis_title = fig.layout.xaxis.title.text
891
+ yaxis_title = fig.layout.yaxis.title.text
892
+
893
+ # Update the combined figure's subplot with the titles
894
+ fig_combined.update_xaxes(title_text=xaxis_title, row=row, col=col)
895
+ fig_combined.update_yaxes(title_text=yaxis_title, row=row, col=col)
896
+
897
+ col += 1
898
+ if col > figures_per_row:
899
+ row += 1
900
+ col = 1
901
+
902
+ info = option_manager.get_project_data()
903
+ folder = os.path.join(info['path'], info['name'])
904
+
905
+ fig = fig_combined
906
+ fig.update_layout(
907
+ title="",
908
+ font=dict(color=theme_font_color[theme]),
909
+ paper_bgcolor=theme_background_color[theme],
910
+ plot_bgcolor=theme_plot_color[theme]
911
+ )
912
+ if (theme == "Publication"):
913
+ fig.update_layout(
914
+ font=dict(
915
+ size=16
916
+ ),
917
+ legend=dict(
918
+ orientation="h",
919
+ yanchor="bottom",
920
+ y=1.02,
921
+ xanchor="center",
922
+ x=0.47
923
+ ),
924
+ margin=dict(
925
+ t=0,
926
+ b=1,
927
+ l=1,
928
+ r=1,
929
+ autoexpand=True
930
+ )
931
+ )
932
+
933
+ if not os.path.exists(folder):
934
+ os.makedirs(folder)
935
+
936
+ fig.write_image(os.path.join(folder, "matrix_editor.png"), width=1280, height=720)
937
+ fig.write_html(os.path.join(folder, "matrix_editor.html"), include_plotlyjs='cdn', auto_open=False)
938
+ fig.write_json(os.path.join(folder, "matrix_editor.json"))
939
+ fig.write_image(os.path.join(folder, "matrix_editor.pdf"), engine="kaleido", width=baseFigureWidth, height=baseFigureHeight)
940
+ with open(os.path.join(folder, "matrix_editor.html"), "r") as f:
941
+ html = f.read()
942
+ html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
943
+ with open(os.path.join(folder, "matrix_editor.html"), "w") as f:
944
+ f.write(html)
945
+
275
946
  return fig