mg-pso-gui 0.1.40__py3-none-any.whl → 0.2.75__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.
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