mg-pso-gui 0.1.13__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 (52) hide show
  1. {mg_pso_gui-0.1.13.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.13.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 +565 -513
  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 +89 -35
  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 +399 -0
  25. mgpsogui/gui/VisualizeTab/VisualizeTab.py +76 -11
  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/gui/images/test.png +0 -0
  32. mgpsogui/util/GraphGenerator.py +747 -42
  33. mgpsogui/util/PSORunner.py +608 -116
  34. mgpsogui/util/debug.py +559 -0
  35. mgpsogui/util/helpers.py +95 -0
  36. mgpsogui/util/recosu/__init__.py +2 -1
  37. mgpsogui/util/recosu/pso/csip_access.py +2 -35
  38. mgpsogui/util/recosu/pso/pso.py +55 -59
  39. mgpsogui/util/recosu/sampling/__init__.py +16 -0
  40. mgpsogui/util/recosu/sampling/halton/__init__.py +0 -0
  41. mgpsogui/util/recosu/sampling/halton/halton.py +45 -0
  42. mgpsogui/util/recosu/sampling/halton/prime.py +82 -0
  43. mgpsogui/util/recosu/sampling/random/__init__.py +0 -0
  44. mgpsogui/util/recosu/sampling/random/random_sampler.py +34 -0
  45. mgpsogui/util/recosu/sampling/sample_trace_writer.py +47 -0
  46. mgpsogui/util/recosu/sampling/sampler_task.py +75 -0
  47. mgpsogui/util/recosu/sampling/sampling.py +99 -0
  48. mgpsogui/util/sampler_test_driver.py +129 -0
  49. mg_pso_gui-0.1.13.dist-info/RECORD +0 -50
  50. mgpsogui/gui/images/IGOW 4 Logo.png +0 -0
  51. {mg_pso_gui-0.1.13.dist-info → mg_pso_gui-0.2.75.dist-info}/entry_points.txt +0 -0
  52. {mg_pso_gui-0.1.13.dist-info → mg_pso_gui-0.2.75.dist-info}/top_level.txt +0 -0
@@ -1,42 +1,166 @@
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
7
+ from PIL import Image, ImageTk
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
+ ]
64
+
65
+ def generate_graphs(HomePage):
66
+
67
+ try:
68
+ selected_graph = HomePage.option_manager.get("selected_graph").get()
69
+ folder = HomePage.option_manager.get_project_folder()
70
+ if not os.path.exists(folder):
71
+ os.makedirs(folder)
72
+
73
+ if (selected_graph == "Best Cost Stacked"):
74
+ HomePage.selected_graph_name = "best_cost_stacked"
75
+ best_cost_stacked(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
76
+ elif (selected_graph == "Best Cost by Round"):
77
+ HomePage.selected_graph_name = "best_cost_by_round"
78
+ best_cost_by_round(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
79
+ elif (selected_graph == "Iteration Table"):
80
+ HomePage.selected_graph_name = "table"
81
+ table(HomePage, HomePage.running_config['steps'], HomePage.progress_data, HomePage.option_manager)
82
+ elif (selected_graph == "Calibrated Parameters"):
83
+ HomePage.selected_graph_name = "calibrated_params_by_round"
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
98
+
99
+ image_path = os.path.join(folder, HomePage.selected_graph_name + ".png")
100
+
101
+ if not os.path.exists(image_path):
102
+ image_path = os.path.join("./images", "up.png")
103
+
104
+ HomePage.graph_image_obj = Image.open(image_path)
105
+ HomePage.graph_image = customtkinter.CTkImage(HomePage.graph_image_obj, size=(HomePage.image_width * HomePage.image_scale, HomePage.image_height * HomePage.image_scale))
106
+ HomePage.graph_label.configure(image=HomePage.graph_image)
107
+ except Exception as e:
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()
6
115
 
7
- def best_cost_stacked(config, dataframe, option_manager):
8
116
  fig = go.Figure()
9
117
 
10
118
  total_steps = len(config)
11
119
 
12
120
  # Get unique values from the round_step column of the dataframe
13
- for iteration in dataframe['round_step'].unique():
14
- # Get best_cost and completed rounds rows for this iteration
15
- df = dataframe[dataframe['round_step'] == iteration]
16
-
17
- step_index = ((iteration) % total_steps)
18
- round_index = ((iteration) // total_steps)
19
-
20
- 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
21
125
 
22
126
  fig.update_layout(
23
127
  title="",
24
- xaxis_title="Iteration",
128
+ xaxis_title="Progress (% through Group)",
25
129
  yaxis_title="Best Cost",
26
- font=dict(color='white'),
27
- paper_bgcolor='rgba(42, 42, 42, 0)',
28
- 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],
29
133
  xaxis=dict(
30
- gridcolor='rgb(72, 72, 72)',
134
+ gridcolor=theme_grid_color[theme],
31
135
  gridwidth=1
32
136
  ),
33
137
  yaxis=dict(
34
138
  range=[0, 0.6],
35
139
  autorange=True,
36
- gridcolor='rgb(72, 72, 72)',
140
+ gridcolor=theme_grid_color[theme],
37
141
  gridwidth=0.1
38
142
  )
39
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
+ )
40
164
 
41
165
  info = option_manager.get_project_data()
42
166
  folder = os.path.join(info['path'], info['name'])
@@ -46,6 +170,8 @@ def best_cost_stacked(config, dataframe, option_manager):
46
170
 
47
171
  fig.write_image(os.path.join(folder, "best_cost_stacked.png"), width=1280, height=720)
48
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)
49
175
  with open(os.path.join(folder, "best_cost_stacked.html"), "r") as f:
50
176
  html = f.read()
51
177
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -55,7 +181,9 @@ def best_cost_stacked(config, dataframe, option_manager):
55
181
 
56
182
  return fig
57
183
 
58
- def table(config, dataframe, option_manager):
184
+ def table(homepage, config, dataframe, option_manager):
185
+ theme = homepage.option_manager.get("graph_theme").get()
186
+
59
187
  # Create a plotly table with the values in the dataframe
60
188
  fig = go.Figure(data=[go.Table(
61
189
  header=dict(
@@ -73,20 +201,40 @@ def table(config, dataframe, option_manager):
73
201
  title="",
74
202
  xaxis_title="Iteration",
75
203
  yaxis_title="Best Cost",
76
- font=dict(color='white'),
77
- paper_bgcolor='rgba(42, 42, 42, 0)',
78
- 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],
79
207
  xaxis=dict(
80
- gridcolor='rgb(72, 72, 72)',
208
+ gridcolor=theme_grid_color[theme],
81
209
  gridwidth=1
82
210
  ),
83
211
  yaxis=dict(
84
212
  range=[0, 0.6],
85
213
  autorange=True,
86
- gridcolor='rgb(72, 72, 72)',
214
+ gridcolor=theme_grid_color[theme],
87
215
  gridwidth=0.1
88
216
  )
89
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
+ )
90
238
 
91
239
  info = option_manager.get_project_data()
92
240
  folder = os.path.join(info['path'], info['name'])
@@ -96,6 +244,8 @@ def table(config, dataframe, option_manager):
96
244
 
97
245
  fig.write_image(os.path.join(folder, "table.png"), width=1280, height=720)
98
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)
99
249
  with open(os.path.join(folder, "table.html"), "r") as f:
100
250
  html = f.read()
101
251
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -104,22 +254,33 @@ def table(config, dataframe, option_manager):
104
254
 
105
255
  return fig
106
256
 
107
- 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
+
108
260
  fig = go.Figure()
109
261
 
110
262
  total_steps = len(config)
111
263
 
264
+ pp = 0
112
265
  # Get unique values from the round_step column of the dataframe
113
- for iteration in dataframe['round_step'].unique():
266
+ for round_step in data.keys():
267
+ #for iteration in dataframe['round_step'].unique():
114
268
  # Get best_cost and completed rounds rows for this iteration
115
- 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]
116
273
 
117
- step_index = ((iteration) % total_steps)
118
- 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)))
119
281
 
120
- fig.add_trace(go.Scatter(x=df['completed_rounds'] + (df['total_rounds'] * round_index), y=df['best_cost'], name='Group ' + str(step_index + 1)))
121
282
 
122
- 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))
123
284
  fig.add_shape(
124
285
  type='line',
125
286
  x0=xx,
@@ -128,7 +289,7 @@ def best_cost_by_round(config, dataframe, option_manager):
128
289
  y1=1,
129
290
  yref='paper',
130
291
  line=dict(
131
- color='rgb(102, 102, 102)',
292
+ color=theme_line_color[theme],
132
293
  width=2
133
294
  )
134
295
  )
@@ -144,22 +305,42 @@ def best_cost_by_round(config, dataframe, option_manager):
144
305
 
145
306
  fig.update_layout(
146
307
  title="",
147
- xaxis_title="Iteration",
308
+ xaxis_title="Progress (%)",
148
309
  yaxis_title="Best Cost",
149
- font=dict(color='white'),
150
- paper_bgcolor='rgba(42, 42, 42, 0)',
151
- 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],
152
313
  xaxis=dict(
153
- gridcolor='rgb(72, 72, 72)',
314
+ gridcolor=theme_grid_color[theme],
154
315
  gridwidth=1
155
316
  ),
156
317
  yaxis=dict(
157
318
  range=[0, 0.6],
158
319
  autorange=True,
159
- gridcolor='rgb(72, 72, 72)',
320
+ gridcolor=theme_grid_color[theme],
160
321
  gridwidth=0.1
161
322
  )
162
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
+ )
163
344
 
164
345
  info = option_manager.get_project_data()
165
346
  folder = os.path.join(info['path'], info['name'])
@@ -169,6 +350,8 @@ def best_cost_by_round(config, dataframe, option_manager):
169
350
 
170
351
  fig.write_image(os.path.join(folder, "best_cost_by_round.png"), width=1280, height=720)
171
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)
172
355
  with open(os.path.join(folder, "best_cost_by_round.html"), "r") as f:
173
356
  html = f.read()
174
357
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
@@ -177,7 +360,9 @@ def best_cost_by_round(config, dataframe, option_manager):
177
360
 
178
361
  return fig
179
362
 
180
- 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
+
181
366
  fig = go.Figure()
182
367
 
183
368
  total_steps = len(config)
@@ -200,29 +385,51 @@ def calibrated_params_by_round(config, list_of_objs, option_manager):
200
385
  round += 1
201
386
 
202
387
  # Get unique values from the round_step column of the dataframe
388
+ pp = 0
203
389
  for key in datalines.keys():
204
390
  # Get best_cost and completed rounds rows for this iteration
205
391
  if key == 'step' or key == 'round':
206
392
  continue
207
393
 
208
- 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
209
396
 
210
397
  fig.update_layout(
211
398
  title="",
212
399
  xaxis_title="Round",
213
400
  yaxis_title="Particle Parameters",
214
- font=dict(color='white'),
215
- paper_bgcolor='rgba(42, 42, 42, 0)',
216
- 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],
217
404
  xaxis=dict(
218
- gridcolor='rgb(72, 72, 72)',
405
+ gridcolor=theme_grid_color[theme],
219
406
  gridwidth=1
220
407
  ),
221
408
  yaxis=dict(
222
- gridcolor='rgb(72, 72, 72)',
409
+ gridcolor=theme_grid_color[theme],
223
410
  gridwidth=0.1
224
411
  )
225
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
+ )
226
433
 
227
434
  info = option_manager.get_project_data()
228
435
  folder = os.path.join(info['path'], info['name'])
@@ -232,10 +439,508 @@ def calibrated_params_by_round(config, list_of_objs, option_manager):
232
439
 
233
440
  fig.write_image(os.path.join(folder, "calibrated_params_by_round.png"), width=1280, height=720)
234
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)
235
444
  with open(os.path.join(folder, "calibrated_params_by_round.html"), "r") as f:
236
445
  html = f.read()
237
446
  html = html.replace("<body>", "<body bgcolor='#2a2a2a'>")
238
447
  with open(os.path.join(folder, "calibrated_params_by_round.html"), "w") as f:
239
448
  f.write(html)
240
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
+
241
946
  return fig