rubycond_of 0.2.0__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.
- rubycond_OF/example/Ruby_example.dat +1025 -0
- rubycond_OF/example/example_use_of.py +76 -0
- rubycond_OF/model/OF_Model.py +79 -0
- rubycond_OF/rubycond_OF.py +345 -0
- rubycond_OF/view/OF_View.py +881 -0
- rubycond_OF/view/OF_about.py +237 -0
- rubycond_OF/view/logo_CP_Scaled.png +0 -0
- rubycond_OF/view/logo_IMPMC_Scaled.png +0 -0
- rubycond_OF/view/manual.pdf +0 -0
- rubycond_of-0.2.0.dist-info/METADATA +103 -0
- rubycond_of-0.2.0.dist-info/RECORD +13 -0
- rubycond_of-0.2.0.dist-info/WHEEL +4 -0
- rubycond_of-0.2.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,881 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
Title: OF_View: tool for opening data files in the most common formats
|
|
5
|
+
|
|
6
|
+
This file is part of Rubycond: Pressure by Ruby Luminescence (PRL) software to determine pressure in diamond anvil cell experiments.
|
|
7
|
+
|
|
8
|
+
Version 0.2.0
|
|
9
|
+
Release 260301
|
|
10
|
+
|
|
11
|
+
Author:
|
|
12
|
+
|
|
13
|
+
Yiuri Garino
|
|
14
|
+
yiuri.garino@cnrs.fr
|
|
15
|
+
|
|
16
|
+
Copyright (c) 2023-2026 Yiuri Garino
|
|
17
|
+
|
|
18
|
+
Download:
|
|
19
|
+
https://github.com/CelluleProjet/Rubycond_OF
|
|
20
|
+
|
|
21
|
+
License: GPLv3
|
|
22
|
+
|
|
23
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
24
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
25
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def reset():
|
|
30
|
+
import sys
|
|
31
|
+
|
|
32
|
+
if hasattr(sys, 'ps1'):
|
|
33
|
+
|
|
34
|
+
#clean Console and Memory
|
|
35
|
+
from IPython import get_ipython
|
|
36
|
+
get_ipython().run_line_magic('clear','/')
|
|
37
|
+
get_ipython().run_line_magic('reset','-sf')
|
|
38
|
+
print("Running interactively")
|
|
39
|
+
print()
|
|
40
|
+
terminal = False
|
|
41
|
+
else:
|
|
42
|
+
print("Running in terminal")
|
|
43
|
+
print()
|
|
44
|
+
terminal = True
|
|
45
|
+
|
|
46
|
+
if __name__ == '__main__':
|
|
47
|
+
reset()
|
|
48
|
+
|
|
49
|
+
import configparser as cp
|
|
50
|
+
from pathlib import Path
|
|
51
|
+
import numpy as np
|
|
52
|
+
import matplotlib.pyplot as plt
|
|
53
|
+
from matplotlib.lines import Line2D
|
|
54
|
+
from matplotlib.backend_bases import MouseEvent
|
|
55
|
+
from datetime import datetime
|
|
56
|
+
import sys
|
|
57
|
+
import os
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
from StringIO import StringIO
|
|
61
|
+
except ImportError:
|
|
62
|
+
from io import StringIO
|
|
63
|
+
|
|
64
|
+
from PyQt5 import QtWidgets, QtCore, QtGui
|
|
65
|
+
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
|
66
|
+
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
|
|
67
|
+
|
|
68
|
+
import traceback
|
|
69
|
+
|
|
70
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
71
|
+
|
|
72
|
+
class Data_Table(QtWidgets.QTableWidget):
|
|
73
|
+
def __init__(self, model, debug = False):
|
|
74
|
+
super().__init__()
|
|
75
|
+
self.__name__ = 'Rubycond Open File View'
|
|
76
|
+
self.__version__ = '0.2.0'
|
|
77
|
+
self.__release__ = '260301'
|
|
78
|
+
self.model = model
|
|
79
|
+
self.debug = debug
|
|
80
|
+
if self.debug : print('\nData_Table\n')
|
|
81
|
+
|
|
82
|
+
self.setColumnCount(5)
|
|
83
|
+
self.setRowCount(5)
|
|
84
|
+
layout = QtWidgets.QVBoxLayout()
|
|
85
|
+
layout.addWidget(self)
|
|
86
|
+
|
|
87
|
+
def error_box(self, title):
|
|
88
|
+
msgBox = QtWidgets.QMessageBox()
|
|
89
|
+
msgBox.setIcon(QtWidgets.QMessageBox.Critical)
|
|
90
|
+
msgBox.setWindowTitle(str(title))
|
|
91
|
+
msgBox.setText(traceback.format_exc())
|
|
92
|
+
msgBox.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
|
|
93
|
+
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
94
|
+
msgBox.exec()
|
|
95
|
+
|
|
96
|
+
def reset(self):
|
|
97
|
+
tot = self.rowCount()
|
|
98
|
+
for i in range(tot+1):
|
|
99
|
+
self.removeColumn(i)
|
|
100
|
+
|
|
101
|
+
def set_numpy_2D(self, data):
|
|
102
|
+
try:
|
|
103
|
+
self.clear()
|
|
104
|
+
row, col = data.shape
|
|
105
|
+
self.model.table_row = row
|
|
106
|
+
self.model.table_col = col
|
|
107
|
+
self.setColumnCount(col)
|
|
108
|
+
self.setRowCount(row)
|
|
109
|
+
for i_r in range(row):
|
|
110
|
+
for i_c in range(col):
|
|
111
|
+
self.setItem(i_r, i_c, QtWidgets.QTableWidgetItem(f'{data[i_r,i_c]:.2f}'))
|
|
112
|
+
except Exception:
|
|
113
|
+
self.error_box('Data_Table set_numpy_2D')
|
|
114
|
+
|
|
115
|
+
def set_str_2D(self, data):
|
|
116
|
+
try:
|
|
117
|
+
self.clear()
|
|
118
|
+
row, col = data.shape
|
|
119
|
+
self.model.table_row = row
|
|
120
|
+
self.model.table_col = col
|
|
121
|
+
self.setColumnCount(col)
|
|
122
|
+
self.setRowCount(row)
|
|
123
|
+
for i_r in range(row):
|
|
124
|
+
for i_c in range(col):
|
|
125
|
+
self.setItem(i_r, i_c, QtWidgets.QTableWidgetItem(data[i_r,i_c]))
|
|
126
|
+
except Exception:
|
|
127
|
+
self.error_box('Data_Table set_str_2D')
|
|
128
|
+
|
|
129
|
+
class show_text_file(QtWidgets.QFrame):
|
|
130
|
+
def __init__(self, filename, debug = False):
|
|
131
|
+
super().__init__()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
self.setWindowTitle(f'file = {str(filename)}')
|
|
135
|
+
try:
|
|
136
|
+
|
|
137
|
+
text_edit = QtWidgets.QPlainTextEdit()
|
|
138
|
+
text=open(filename).read()
|
|
139
|
+
text_edit.setPlainText(text)
|
|
140
|
+
|
|
141
|
+
#Final layout
|
|
142
|
+
|
|
143
|
+
layout = QtWidgets.QVBoxLayout()
|
|
144
|
+
layout.addWidget(text_edit)
|
|
145
|
+
|
|
146
|
+
self.setLayout(layout)
|
|
147
|
+
|
|
148
|
+
self.setSizePolicy(
|
|
149
|
+
QtWidgets.QSizePolicy.Fixed,
|
|
150
|
+
QtWidgets.QSizePolicy.Fixed)
|
|
151
|
+
except Exception:
|
|
152
|
+
self.error_box('Show text file error')
|
|
153
|
+
|
|
154
|
+
def error_box(self, title):
|
|
155
|
+
msgBox = QtWidgets.QMessageBox()
|
|
156
|
+
msgBox.setIcon(QtWidgets.QMessageBox.Critical)
|
|
157
|
+
msgBox.setWindowTitle(str(title))
|
|
158
|
+
msgBox.setText(traceback.format_exc())
|
|
159
|
+
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
160
|
+
msgBox.exec()
|
|
161
|
+
|
|
162
|
+
class open_file_commands(QtWidgets.QFrame):
|
|
163
|
+
|
|
164
|
+
signal_plot_data = QtCore.pyqtSignal(np.ndarray)
|
|
165
|
+
#signal_add_plot = QtCore.pyqtSignal(np.ndarray)
|
|
166
|
+
signal_fill_float_table = QtCore.pyqtSignal(np.ndarray)
|
|
167
|
+
signal_fill_str_table = QtCore.pyqtSignal(np.ndarray)
|
|
168
|
+
|
|
169
|
+
signal_selected_data_all = QtCore.pyqtSignal(np.ndarray, str)
|
|
170
|
+
signal_selected_data_xy = QtCore.pyqtSignal(np.ndarray, np.ndarray, str)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
signal_quit = QtCore.pyqtSignal()
|
|
175
|
+
|
|
176
|
+
def __init__(self, model, debug = False, about = None):
|
|
177
|
+
super().__init__()
|
|
178
|
+
self.model = model
|
|
179
|
+
self.debug = debug
|
|
180
|
+
self.about = about
|
|
181
|
+
|
|
182
|
+
if self.debug : print('\nopen_file_commands\n')
|
|
183
|
+
|
|
184
|
+
self.file_data = None
|
|
185
|
+
self.file_data_i_x = 0 #Default value X data = column 0
|
|
186
|
+
self.file_data_i_y = 1 #Default value Y data = column 1
|
|
187
|
+
self.flag_custom_file = False
|
|
188
|
+
self.loadtxt_comments = ['#', '"']
|
|
189
|
+
self.loadtxt_delimiter = r' '
|
|
190
|
+
self.loadtxt_skiprows = 0
|
|
191
|
+
|
|
192
|
+
self.max_width = 300
|
|
193
|
+
|
|
194
|
+
self.label_decimal = QtWidgets.QLabel(self)
|
|
195
|
+
self.label_decimal.setText('Decimal separator')
|
|
196
|
+
|
|
197
|
+
#(['Decimal separator = point .', 'Decimal separator = comma ,'])
|
|
198
|
+
|
|
199
|
+
self.combobox_decimal_separator = QtWidgets.QComboBox()
|
|
200
|
+
self.combobox_decimal_separator.addItems(['point .', 'comma ,'])
|
|
201
|
+
self.combobox_decimal_separator.currentIndexChanged.connect(self.combobox_decimal_separator_index_changed)
|
|
202
|
+
|
|
203
|
+
self.button_Open_npy = QtWidgets.QPushButton("Open numpy (npy)")
|
|
204
|
+
self.button_Open_npy.clicked.connect(self.open_data_File_npy)
|
|
205
|
+
|
|
206
|
+
self.button_Open_csv = QtWidgets.QPushButton("Open comma delimiter (csv)")
|
|
207
|
+
self.button_Open_csv.clicked.connect(self.open_data_File_csv)
|
|
208
|
+
|
|
209
|
+
self.button_Open_dat = QtWidgets.QPushButton("Open space/tab delimiter (txt, dat)")
|
|
210
|
+
self.button_Open_dat.clicked.connect(self.open_data_File_dat)
|
|
211
|
+
|
|
212
|
+
#self.button_Open_tab = QtWidgets.QPushButton("Open tab delimiter")
|
|
213
|
+
#self.button_Open_tab.clicked.connect(self.open_data_File_tab)
|
|
214
|
+
|
|
215
|
+
self.button_Show_preview = QtWidgets.QPushButton("Show plain text")
|
|
216
|
+
self.button_Show_preview.clicked.connect(self.open_Show_preview)
|
|
217
|
+
|
|
218
|
+
self.button_Open_custom = QtWidgets.QPushButton("Open")
|
|
219
|
+
self.button_Open_custom.clicked.connect(self.open_data_File_custom)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
self.label_comments = QtWidgets.QLabel(self)
|
|
223
|
+
self.label_comments.setText('Commented lines (ch)')
|
|
224
|
+
|
|
225
|
+
self.label_delimiter = QtWidgets.QLabel(self)
|
|
226
|
+
self.label_delimiter.setText('Columns delimiter')
|
|
227
|
+
|
|
228
|
+
self.label_skiprows = QtWidgets.QLabel(self)
|
|
229
|
+
self.label_skiprows.setText('Skip first (n) lines')
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
self.button_about = QtWidgets.QPushButton("About Open File")
|
|
233
|
+
self.button_about.clicked.connect(self.open_about)
|
|
234
|
+
|
|
235
|
+
_ =''
|
|
236
|
+
for i in self.loadtxt_comments:
|
|
237
|
+
_ = _ + i
|
|
238
|
+
self.open_button_comments = QtWidgets.QPushButton(_)
|
|
239
|
+
self.open_button_comments.clicked.connect(self.command_button_comments)
|
|
240
|
+
|
|
241
|
+
'''ComboBox better ?
|
|
242
|
+
self.label_loadtxt_delimiter = QtWidgets.QLineEdit(self, placeholderText=self.loadtxt_delimiter,
|
|
243
|
+
clearButtonEnabled=True)
|
|
244
|
+
#self.label_loadtxt_delimiter.returnPressed.connect(self.change_loadtxt_delimiter)
|
|
245
|
+
'''
|
|
246
|
+
|
|
247
|
+
self.combobox_loadtxt_delimiter = QtWidgets.QComboBox()
|
|
248
|
+
self.combobox_loadtxt_delimiter.addItems(['space', 'tab', 'comma ,', 'semicolon ;'])
|
|
249
|
+
self.combobox_loadtxt_delimiter.currentIndexChanged.connect(self.combobox_loadtxt_delimiter_index_changed)
|
|
250
|
+
|
|
251
|
+
#self.label_loadtxt_skiprows = QtWidgets.QLineEdit(self, placeholderText=str(self.loadtxt_skiprows),clearButtonEnabled=True)
|
|
252
|
+
#self.label_loadtxt_skiprows.returnPressed.connect(self.change_loadtxt_skiprows)
|
|
253
|
+
#Plot Commands
|
|
254
|
+
|
|
255
|
+
self.open_button_skiprows = QtWidgets.QPushButton("0")
|
|
256
|
+
self.open_button_skiprows.clicked.connect(self.command_button_skiprows)
|
|
257
|
+
|
|
258
|
+
self.open_button_skiprows
|
|
259
|
+
|
|
260
|
+
self.button_Plot_data = QtWidgets.QPushButton("Plot")
|
|
261
|
+
#self.button_Plot_data.clicked.connect(self.open_data_File_custom)
|
|
262
|
+
|
|
263
|
+
self.label_plot_x = QtWidgets.QLabel(self)
|
|
264
|
+
self.label_plot_x.setText('X Data')
|
|
265
|
+
|
|
266
|
+
self.combobox_Plot_data_column_x = QtWidgets.QComboBox()
|
|
267
|
+
|
|
268
|
+
self.label_plot_y = QtWidgets.QLabel(self)
|
|
269
|
+
self.label_plot_y.setText('Y Data')
|
|
270
|
+
|
|
271
|
+
self.combobox_Plot_data_column_y = QtWidgets.QComboBox()
|
|
272
|
+
|
|
273
|
+
self.button_Delete_plot = QtWidgets.QPushButton("Delete")
|
|
274
|
+
#self.button_Delete_plot.clicked.connect(self.open_data_File_custom)
|
|
275
|
+
|
|
276
|
+
self.combobox_button_Delete_plot = QtWidgets.QComboBox()
|
|
277
|
+
|
|
278
|
+
#Accept Close Commands
|
|
279
|
+
self.button_Accept = QtWidgets.QPushButton("Accept")
|
|
280
|
+
self.button_Accept.setStyleSheet("background-color: limegreen"); #lightgreen
|
|
281
|
+
self.button_Accept.clicked.connect(self.app_accept_quit)
|
|
282
|
+
|
|
283
|
+
self.combobox_Accept_data_column_x = QtWidgets.QComboBox()
|
|
284
|
+
self.combobox_Accept_data_column_y = QtWidgets.QComboBox()
|
|
285
|
+
|
|
286
|
+
self.button_Cancel = QtWidgets.QPushButton("Cancel")
|
|
287
|
+
self.button_Cancel.setStyleSheet("background-color: red");
|
|
288
|
+
self.button_Cancel.clicked.connect(self.app_quit)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
Widget_Open = QtWidgets.QWidget()
|
|
293
|
+
Widget_Open.setMaximumWidth(self.max_width)
|
|
294
|
+
Widget_Open.setObjectName('Widget_Open')
|
|
295
|
+
Widget_Open.setStyleSheet("#Widget_Open {border: 2px solid green; border-radius: 10px;}")
|
|
296
|
+
|
|
297
|
+
layout_Open = QtWidgets.QGridLayout(Widget_Open)
|
|
298
|
+
|
|
299
|
+
layout_Open.addWidget(self.label_decimal, 0, 1)
|
|
300
|
+
layout_Open.addWidget(self.combobox_decimal_separator, 0, 2)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
#layout_Open.addWidget(self.button_Open_csv, 2, 1)
|
|
304
|
+
#layout_Open.addWidget(self.button_Open_dat, 3, 1)
|
|
305
|
+
|
|
306
|
+
layout_Open.addWidget(self.label_comments, 1, 1)
|
|
307
|
+
layout_Open.addWidget(self.label_delimiter, 2, 1)
|
|
308
|
+
layout_Open.addWidget(self.label_skiprows, 3, 1)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
#layout_Open.addWidget(self.label_loadtxt_comments, 1, 2)
|
|
313
|
+
layout_Open.addWidget(self.open_button_comments, 1, 2)
|
|
314
|
+
layout_Open.addWidget(self.combobox_loadtxt_delimiter, 2, 2)
|
|
315
|
+
layout_Open.addWidget(self.open_button_skiprows, 3, 2)
|
|
316
|
+
|
|
317
|
+
layout_Open.addWidget(self.button_Open_custom, 4, 1)
|
|
318
|
+
|
|
319
|
+
Widget_numpy = QtWidgets.QWidget()
|
|
320
|
+
Widget_numpy.setMaximumWidth(self.max_width)
|
|
321
|
+
Widget_numpy.setObjectName('Widget_numpy')
|
|
322
|
+
Widget_numpy.setStyleSheet("#Widget_numpy {border: 2px solid green; border-radius: 10px;}")
|
|
323
|
+
|
|
324
|
+
layout_numpy = QtWidgets.QGridLayout(Widget_numpy)
|
|
325
|
+
layout_numpy.addWidget(self.button_Open_npy, 1, 1)
|
|
326
|
+
|
|
327
|
+
Widget_text = QtWidgets.QWidget()
|
|
328
|
+
Widget_text.setMaximumWidth(self.max_width)
|
|
329
|
+
Widget_text.setObjectName('Widget_Text')
|
|
330
|
+
Widget_text.setStyleSheet("#Widget_Text {border: 2px solid black; border-radius: 10px;}")
|
|
331
|
+
|
|
332
|
+
layout_text = QtWidgets.QGridLayout(Widget_text)
|
|
333
|
+
layout_text.addWidget(self.button_Show_preview, 0, 1)
|
|
334
|
+
|
|
335
|
+
# Widget_Custom = QtWidgets.QWidget()
|
|
336
|
+
# Widget_Custom.setMaximumWidth(self.max_width)
|
|
337
|
+
# Widget_Custom.setObjectName('Widget_Custom')
|
|
338
|
+
# Widget_Custom.setStyleSheet("#Widget_Custom {border: 2px solid green; border-radius: 10px;}")
|
|
339
|
+
|
|
340
|
+
# layout_Custom = QtWidgets.QGridLayout(Widget_Custom)
|
|
341
|
+
|
|
342
|
+
# layout_Custom.addWidget(self.label_comments, 1, 1)
|
|
343
|
+
# layout_Custom.addWidget(self.label_delimiter, 2, 1)
|
|
344
|
+
# layout_Custom.addWidget(self.label_skiprows, 3, 1)
|
|
345
|
+
# layout_Custom.addWidget(self.button_Open_custom, 4, 1)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
# layout_Custom.addWidget(self.label_loadtxt_comments, 1, 2)
|
|
349
|
+
# layout_Custom.addWidget(self.combobox_loadtxt_delimiter, 2, 2)
|
|
350
|
+
# layout_Custom.addWidget(self.label_loadtxt_skiprows, 3, 2)
|
|
351
|
+
|
|
352
|
+
#Plot Widget
|
|
353
|
+
Widget_Plot = QtWidgets.QWidget()
|
|
354
|
+
Widget_Plot.setMaximumWidth(self.max_width)
|
|
355
|
+
Widget_Plot.setObjectName('Widget_Close')
|
|
356
|
+
Widget_Plot.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
|
|
357
|
+
|
|
358
|
+
layout_Plot = QtWidgets.QGridLayout(Widget_Plot)
|
|
359
|
+
layout_Plot.addWidget(self.button_Plot_data, 1, 1)
|
|
360
|
+
layout_Plot.addWidget(self.label_plot_x, 2, 1)
|
|
361
|
+
layout_Plot.addWidget(self.label_plot_y, 3, 1)
|
|
362
|
+
layout_Plot.addWidget(self.combobox_Plot_data_column_x, 2, 2)
|
|
363
|
+
layout_Plot.addWidget(self.combobox_Plot_data_column_y, 3, 2)
|
|
364
|
+
layout_Plot.addWidget(self.button_Delete_plot, 4, 1)
|
|
365
|
+
layout_Plot.addWidget(self.combobox_button_Delete_plot, 4, 2)
|
|
366
|
+
|
|
367
|
+
#Accept Close Widget
|
|
368
|
+
Widget_Close = QtWidgets.QWidget()
|
|
369
|
+
Widget_Close.setMaximumWidth(self.max_width)
|
|
370
|
+
Widget_Close.setObjectName('Widget_Close')
|
|
371
|
+
Widget_Close.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
|
|
372
|
+
|
|
373
|
+
layout_Close = QtWidgets.QGridLayout(Widget_Close)
|
|
374
|
+
layout_Close.addWidget(self.button_Accept, 1, 1)
|
|
375
|
+
layout_Close.addWidget(self.combobox_Accept_data_column_x, 1, 2)
|
|
376
|
+
layout_Close.addWidget(self.combobox_Accept_data_column_y, 1, 3)
|
|
377
|
+
layout_Close.addWidget(self.button_Cancel, 2, 1, 1, 3) #, columnSpan = 3)
|
|
378
|
+
|
|
379
|
+
#About Widget
|
|
380
|
+
Widget_About = QtWidgets.QWidget()
|
|
381
|
+
Widget_About.setMaximumWidth(self.max_width)
|
|
382
|
+
Widget_About.setObjectName('Widget_About')
|
|
383
|
+
#Widget_About.setStyleSheet("#Widget_Close {border: 2px solid blue; border-radius: 10px;}")
|
|
384
|
+
|
|
385
|
+
layout_About = QtWidgets.QGridLayout(Widget_About)
|
|
386
|
+
layout_About.addWidget(self.button_about, 1, 1)
|
|
387
|
+
|
|
388
|
+
#Final layout
|
|
389
|
+
|
|
390
|
+
layout_controls = QtWidgets.QVBoxLayout()
|
|
391
|
+
|
|
392
|
+
layout_controls.addWidget(Widget_About)
|
|
393
|
+
layout_controls.addWidget(Widget_text)
|
|
394
|
+
layout_controls.addWidget(Widget_Open)
|
|
395
|
+
#layout_controls.addWidget(Widget_Custom)
|
|
396
|
+
layout_controls.addWidget(Widget_numpy)
|
|
397
|
+
|
|
398
|
+
layout_controls.addWidget(Widget_Plot)
|
|
399
|
+
layout_controls.addWidget(Widget_Close)
|
|
400
|
+
|
|
401
|
+
layout_controls.setAlignment(QtCore.Qt.AlignTop)
|
|
402
|
+
# layout_controls = QtWidgets.QVBoxLayout()
|
|
403
|
+
|
|
404
|
+
# layout_controls.addWidget(button_Open_csv)
|
|
405
|
+
# layout_controls.addWidget(button_Open_dat)
|
|
406
|
+
# layout_controls.addWidget(button_Open_custom)
|
|
407
|
+
# #layout_controls.addWidget(self.combo)
|
|
408
|
+
|
|
409
|
+
# layout_controls.addWidget(button_Accept)
|
|
410
|
+
# layout_controls.addWidget(button_Cancel)
|
|
411
|
+
# layout_controls.setAlignment(QtCore.Qt.AlignTop)
|
|
412
|
+
|
|
413
|
+
self.setLayout(layout_controls)
|
|
414
|
+
|
|
415
|
+
self.setSizePolicy(
|
|
416
|
+
QtWidgets.QSizePolicy.Fixed,
|
|
417
|
+
QtWidgets.QSizePolicy.Fixed)
|
|
418
|
+
|
|
419
|
+
def open_about(self):
|
|
420
|
+
if self.about is not None:
|
|
421
|
+
self.about.show()
|
|
422
|
+
|
|
423
|
+
def command_button_comments(self):
|
|
424
|
+
title = 'New comment character'
|
|
425
|
+
label = 'The characters or list of characters used to indicate the start of a comment'
|
|
426
|
+
|
|
427
|
+
new_value, ok = QtWidgets.QInputDialog.getText(self, title, label)
|
|
428
|
+
if ok:
|
|
429
|
+
self.loadtxt_comments = list(new_value)
|
|
430
|
+
self.open_button_comments.setText(new_value)
|
|
431
|
+
self.model.statusbar_message('Commented lines (ch) = ' + '|'.join(self.loadtxt_comments))
|
|
432
|
+
|
|
433
|
+
def command_button_skiprows(self):
|
|
434
|
+
title = 'New skip lines number'
|
|
435
|
+
label = 'Skip the first n lines, including comments'
|
|
436
|
+
|
|
437
|
+
new_value, ok = QtWidgets.QInputDialog.getInt(self, title, label, self.loadtxt_skiprows, 0)
|
|
438
|
+
if ok:
|
|
439
|
+
self.loadtxt_skiprows = new_value
|
|
440
|
+
self.open_button_skiprows.setText(str(new_value))
|
|
441
|
+
self.model.statusbar_message('Skip the first ' + str(self.loadtxt_skiprows0 + ' lines, including comments'))
|
|
442
|
+
|
|
443
|
+
def error_box(self, title : str):
|
|
444
|
+
msgBox = QtWidgets.QMessageBox()
|
|
445
|
+
msgBox.setIcon(QtWidgets.QMessageBox.Critical)
|
|
446
|
+
msgBox.setWindowTitle(str(title))
|
|
447
|
+
msgBox.setText(traceback.format_exc())
|
|
448
|
+
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
449
|
+
msgBox.exec()
|
|
450
|
+
|
|
451
|
+
def error_message(self, title : str, error : str):
|
|
452
|
+
msgBox = QtWidgets.QMessageBox()
|
|
453
|
+
msgBox.setIcon(QtWidgets.QMessageBox.Critical)
|
|
454
|
+
msgBox.setWindowTitle(title)
|
|
455
|
+
msgBox.setText(error)
|
|
456
|
+
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
457
|
+
msgBox.exec()
|
|
458
|
+
|
|
459
|
+
def open_Show_preview(self):
|
|
460
|
+
self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
|
|
461
|
+
if self.fileName:
|
|
462
|
+
self.model.statusbar_message(message = "Open plain text")
|
|
463
|
+
self.show_text_file = show_text_file(self.fileName)
|
|
464
|
+
self.show_text_file.show()
|
|
465
|
+
|
|
466
|
+
def combobox_loadtxt_delimiter_index_changed(self):
|
|
467
|
+
index = self.combobox_decimal_separator.currentIndex()
|
|
468
|
+
# if index = 0:
|
|
469
|
+
# self.loadtxt_delimiter
|
|
470
|
+
# elif index == 1 :
|
|
471
|
+
# ['space', 'tab', 'comma ,', 'semicolon ;']
|
|
472
|
+
|
|
473
|
+
#setItemText
|
|
474
|
+
|
|
475
|
+
def combobox_decimal_separator_index_changed(self):
|
|
476
|
+
index = self.combobox_decimal_separator.currentIndex()
|
|
477
|
+
if self.debug : print(f'combobox_decimal_separator = {index}')
|
|
478
|
+
if index == 0: # point .
|
|
479
|
+
self.button_Open_csv.setText("Open comma delimiter (csv)")
|
|
480
|
+
self.model.statusbar_message(message = "'Decimal separator = point .")
|
|
481
|
+
self.combobox_loadtxt_delimiter.setItemText(2, 'comma ,')
|
|
482
|
+
elif index == 1: # comma ,
|
|
483
|
+
self.button_Open_csv.setText("Open semicolon delimiter (csv)")
|
|
484
|
+
self.model.statusbar_message(message = "'Decimal separator = comma ,")
|
|
485
|
+
self.combobox_loadtxt_delimiter.setItemText(2, 'point .')
|
|
486
|
+
|
|
487
|
+
def open_data_File_csv(self):
|
|
488
|
+
|
|
489
|
+
index = self.combobox_decimal_separator.currentIndex()
|
|
490
|
+
if self.debug : print('open_data_File_csv')
|
|
491
|
+
if index == 0: # point .
|
|
492
|
+
self.open_data_File(delimiter=',')
|
|
493
|
+
self.model.statusbar_message(message = "Open comma delimiter (csv)")
|
|
494
|
+
elif index == 1: # comma ,
|
|
495
|
+
self.open_data_File(delimiter=';')
|
|
496
|
+
self.model.statusbar_message(message = "Open semicolon delimiter (csv)")
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def change_loadtxt_skiprows(self):
|
|
501
|
+
try :
|
|
502
|
+
text = self.label_loadtxt_skiprows.text()
|
|
503
|
+
self.loadtxt_skiprows = int(text)
|
|
504
|
+
self.model.statusbar_message('Skip first (n) lines = ' + self.label_loadtxt_skiprows.text())
|
|
505
|
+
self.label_loadtxt_skiprows.setPlaceholderText(text)
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
except Exception:
|
|
509
|
+
self.model.error_box('open_file_commands change_loadtxt_skiprows')
|
|
510
|
+
self.model.statusbar_message('Skip first (n) lines = ' + self.loadtxt_skiprows)
|
|
511
|
+
|
|
512
|
+
def change_loadtxt_comments(self):
|
|
513
|
+
|
|
514
|
+
try :
|
|
515
|
+
text = self.label_loadtxt_comments.text()
|
|
516
|
+
self.loadtxt_comments = text
|
|
517
|
+
message='Commented lines (ch) = '
|
|
518
|
+
for i in text:
|
|
519
|
+
message = message + i
|
|
520
|
+
self.model.statusbar_message(message)
|
|
521
|
+
self.label_loadtxt_comments.setPlaceholderText(text)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
except Exception:
|
|
525
|
+
self.model.error_box('open_file_commands change_loadtxt_comments')
|
|
526
|
+
self.model.statusbar_message('invalid value, Commented lines (ch) =' + self.loadtxt_comments)
|
|
527
|
+
|
|
528
|
+
def print_time(self, event = None, Message = 'Now = '):
|
|
529
|
+
now = datetime.now()
|
|
530
|
+
current_time = now.strftime("%A %d %B %Y %H:%M:%S")
|
|
531
|
+
print(Message + current_time)
|
|
532
|
+
|
|
533
|
+
def open_data_File_custom(self):
|
|
534
|
+
self.flag_custom_file = True
|
|
535
|
+
|
|
536
|
+
self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
|
|
537
|
+
try:
|
|
538
|
+
|
|
539
|
+
if self.fileName:
|
|
540
|
+
if self.debug: print(self.fileName)
|
|
541
|
+
|
|
542
|
+
loadtxt_delimiter = self.combobox_loadtxt_delimiter.currentText()
|
|
543
|
+
#['space', 'tab', 'comma ,', 'semicolon ;']
|
|
544
|
+
|
|
545
|
+
if loadtxt_delimiter == 'space':
|
|
546
|
+
self.loadtxt_delimiter = ' '
|
|
547
|
+
elif loadtxt_delimiter == 'tab' :
|
|
548
|
+
self.loadtxt_delimiter = '\t'
|
|
549
|
+
elif loadtxt_delimiter == 'comma ,' :
|
|
550
|
+
self.loadtxt_delimiter = ','
|
|
551
|
+
elif loadtxt_delimiter == 'semicolon ;' :
|
|
552
|
+
self.loadtxt_delimiter = ';'
|
|
553
|
+
elif loadtxt_delimiter == 'point .':
|
|
554
|
+
self.loadtxt_delimiter = '.'
|
|
555
|
+
|
|
556
|
+
index = self.combobox_decimal_separator.currentIndex()
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
# if index == 0: # point .
|
|
560
|
+
# s = self.fileName
|
|
561
|
+
# elif index == 1: # comma ,
|
|
562
|
+
# s = open(self.fileName).read().replace(',','.')
|
|
563
|
+
#if self.debug:
|
|
564
|
+
|
|
565
|
+
if self.debug: print(f'delim = {loadtxt_delimiter} = |{self.loadtxt_delimiter}| decimal = |{index}|0=. 1=,')
|
|
566
|
+
_ = ''
|
|
567
|
+
for i in self.loadtxt_delimiter:
|
|
568
|
+
_ = _ + i
|
|
569
|
+
if self.debug: print(f'comments = {self.loadtxt_comments} delim = {_} skip = {self.loadtxt_skiprows}')
|
|
570
|
+
message = f'comments = {self.loadtxt_comments} delim = {self.loadtxt_delimiter} skip = {self.loadtxt_skiprows}'
|
|
571
|
+
self.model.statusbar_message(message)
|
|
572
|
+
|
|
573
|
+
self.file_data = np.loadtxt(self.fileName, dtype = str,
|
|
574
|
+
comments = self.loadtxt_comments,
|
|
575
|
+
delimiter = self.loadtxt_delimiter,
|
|
576
|
+
skiprows = self.loadtxt_skiprows)
|
|
577
|
+
if self.debug: print(self.file_data)
|
|
578
|
+
# print(self.loadtxt_comments)
|
|
579
|
+
# print(self.loadtxt_delimiter)
|
|
580
|
+
# print(self.loadtxt_skiprows)
|
|
581
|
+
# print(len(self.file_data.shape))
|
|
582
|
+
|
|
583
|
+
if len(self.file_data.shape) == 2:
|
|
584
|
+
self.signal_fill_str_table.emit(self.file_data)
|
|
585
|
+
try:
|
|
586
|
+
a = self.file_data[:,0].astype(float)
|
|
587
|
+
b = self.file_data[:,1].astype(float)
|
|
588
|
+
c = np.column_stack((a,b))
|
|
589
|
+
self.signal_plot_data.emit(c)
|
|
590
|
+
except:
|
|
591
|
+
self.error_message('column 1 or column 2 contains text that cannot be converted to numbers')
|
|
592
|
+
else:
|
|
593
|
+
self.error_message('Open data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
|
|
594
|
+
|
|
595
|
+
except Exception:
|
|
596
|
+
self.error_box('open_file_commands open_data_File_custom')
|
|
597
|
+
|
|
598
|
+
def open_data_File_npy(self, delimiter = ''):
|
|
599
|
+
self.model.statusbar_message(message = "Open numpy npy")
|
|
600
|
+
self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File", filter = "numpy files (*.npy)")
|
|
601
|
+
try:
|
|
602
|
+
if self.fileName:
|
|
603
|
+
if self.debug: print(self.fileName)
|
|
604
|
+
self.file_data= np.load(self.fileName)
|
|
605
|
+
|
|
606
|
+
if len(self.file_data.shape) == 2:
|
|
607
|
+
self.signal_plot_data.emit(self.file_data)
|
|
608
|
+
self.signal_fill_float_table.emit(self.file_data)
|
|
609
|
+
else:
|
|
610
|
+
self.error_message('Open numpy data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
|
|
611
|
+
|
|
612
|
+
except Exception:
|
|
613
|
+
self.error_box('open_file_commands open_data_File_npy')
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def open_data_File(self, delimiter = ''):
|
|
617
|
+
self.flag_custom_file = False
|
|
618
|
+
self.fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select File")
|
|
619
|
+
try:
|
|
620
|
+
if self.fileName:
|
|
621
|
+
index = self.combobox_decimal_separator.currentIndex()
|
|
622
|
+
if index == 0: # point .
|
|
623
|
+
self.file_data= np.loadtxt(self.fileName, delimiter = delimiter)
|
|
624
|
+
elif index == 1: # comma ,
|
|
625
|
+
s = open(self.fileName).read().replace(',','.')
|
|
626
|
+
self.file_data= np.loadtxt(StringIO(s), delimiter = delimiter)
|
|
627
|
+
|
|
628
|
+
if len(self.file_data.shape) == 2:
|
|
629
|
+
self.signal_plot_data.emit(self.file_data)
|
|
630
|
+
self.signal_fill_float_table.emit(self.file_data)
|
|
631
|
+
else:
|
|
632
|
+
self.error_message('Open data file error', 'Data must be in a 2D format, at least 2 lines 2 columns')
|
|
633
|
+
|
|
634
|
+
if self.debug: print(self.fileName)
|
|
635
|
+
if self.debug: print(self.file_data)
|
|
636
|
+
except Exception:
|
|
637
|
+
self.error_box('open_file_commands open_data_File')
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
def open_data_File_dat(self):
|
|
642
|
+
self.model.statusbar_message(message = "Open space delimiter")
|
|
643
|
+
self.open_data_File(delimiter= None)
|
|
644
|
+
|
|
645
|
+
def open_data_File_tab(self):
|
|
646
|
+
self.model.statusbar_message(message = "Open tab delimiter")
|
|
647
|
+
self.open_data_File(delimiter='\t')
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
def data_to_model(self, data):
|
|
651
|
+
#Data to model
|
|
652
|
+
self.model.ndarray_from_file = self.ndarray_from_file
|
|
653
|
+
self.model.x_data_from_file = self.ndarray_from_file[:,0]
|
|
654
|
+
self.model.x_data_from_file = self.ndarray_from_file[:,1]
|
|
655
|
+
|
|
656
|
+
def app_quit(self):
|
|
657
|
+
self.signal_quit.emit()
|
|
658
|
+
|
|
659
|
+
def app_accept_quit(self):
|
|
660
|
+
|
|
661
|
+
file_data_i_x = self.combobox_Accept_data_column_x.currentIndex()
|
|
662
|
+
file_data_i_y = self.combobox_Accept_data_column_y.currentIndex()
|
|
663
|
+
print(file_data_i_x)
|
|
664
|
+
print(file_data_i_y)
|
|
665
|
+
try:
|
|
666
|
+
if self.file_data is not None:
|
|
667
|
+
self.file_data = self.file_data.astype(float)
|
|
668
|
+
file_data_i_x = self.combobox_Accept_data_column_x.currentIndex()
|
|
669
|
+
file_data_i_y = self.combobox_Accept_data_column_y.currentIndex()
|
|
670
|
+
try:
|
|
671
|
+
file_data_x = self.file_data[:, file_data_i_x].astype(float)
|
|
672
|
+
file_data_y = self.file_data[:, file_data_i_y].astype(float)
|
|
673
|
+
self.signal_selected_data_all.emit(self.file_data, self.fileName)
|
|
674
|
+
self.signal_selected_data_xy.emit(file_data_x, file_data_y, self.fileName)
|
|
675
|
+
self.signal_quit.emit()
|
|
676
|
+
except:
|
|
677
|
+
print('error')
|
|
678
|
+
choice = QtWidgets.QMessageBox.question(self, "Quit", "Data conversion to numbers failed, exit without data?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
|
|
679
|
+
QtWidgets.QMessageBox()
|
|
680
|
+
if choice == QtWidgets.QMessageBox.Yes:
|
|
681
|
+
self.signal_quit.emit()
|
|
682
|
+
self.signal_selected_data_all.emit(self.file_data, self.fileName)
|
|
683
|
+
else:
|
|
684
|
+
self.signal_quit.emit()
|
|
685
|
+
except Exception:
|
|
686
|
+
self.error_box('open_file_commands app_accept_quit')
|
|
687
|
+
|
|
688
|
+
class Frame_1_graph(QtWidgets.QFrame):
|
|
689
|
+
|
|
690
|
+
signal_fig_on_click = QtCore.pyqtSignal(MouseEvent)
|
|
691
|
+
signal_fig_click_no_drag = QtCore.pyqtSignal(MouseEvent)
|
|
692
|
+
signal_fig_click_drag = QtCore.pyqtSignal(MouseEvent)
|
|
693
|
+
|
|
694
|
+
def __init__(self, model, debug = False):
|
|
695
|
+
|
|
696
|
+
super().__init__()
|
|
697
|
+
self.model = model
|
|
698
|
+
self.debug = debug
|
|
699
|
+
if self.debug: print("\nDebug mode\n")
|
|
700
|
+
if self.debug: self.setStyleSheet("border: 20px solid red")
|
|
701
|
+
|
|
702
|
+
layout = QtWidgets.QVBoxLayout()
|
|
703
|
+
|
|
704
|
+
self.fig_ref = [] #List of plot ref
|
|
705
|
+
self.fig_ref_names = [] #List of plot names
|
|
706
|
+
self.x_min_all = np.inf
|
|
707
|
+
self.x_max_all = -np.inf
|
|
708
|
+
self.y_min_all = np.inf
|
|
709
|
+
self.y_max_all = -np.inf
|
|
710
|
+
self.total_plot_n = 0
|
|
711
|
+
|
|
712
|
+
self.fig = plt.figure(figsize=(5, 5))
|
|
713
|
+
self.canvas = FigureCanvas(self.fig)
|
|
714
|
+
self.canvas.mpl_connect('button_press_event', self.on_click)
|
|
715
|
+
self.canvas.mpl_connect('button_release_event', self.off_click)
|
|
716
|
+
|
|
717
|
+
self.navigationToolbar = NavigationToolbar(self.canvas, self, coordinates=True)
|
|
718
|
+
self.ax = self.fig.add_subplot(111)
|
|
719
|
+
self.ax.grid()
|
|
720
|
+
self.x_moving_ref_left = 0 #Ref to detect drag
|
|
721
|
+
self.y_moving_ref_left = 0 #Ref to detect drag
|
|
722
|
+
#self.navigationToolbar.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
|
723
|
+
|
|
724
|
+
# show canvas
|
|
725
|
+
self.canvas.show()
|
|
726
|
+
|
|
727
|
+
# create main layout
|
|
728
|
+
|
|
729
|
+
layout.addWidget(self.canvas)
|
|
730
|
+
layout.addWidget(self.navigationToolbar)
|
|
731
|
+
|
|
732
|
+
self.setLayout(layout)
|
|
733
|
+
|
|
734
|
+
self.plot_ref = None
|
|
735
|
+
self.data_x = None
|
|
736
|
+
self.data_y = None
|
|
737
|
+
self.plot_simple_calib_ref = None
|
|
738
|
+
|
|
739
|
+
def error_box(self, title):
|
|
740
|
+
msgBox = QtWidgets.QMessageBox()
|
|
741
|
+
msgBox.setIcon(QtWidgets.QMessageBox.Critical)
|
|
742
|
+
msgBox.setWindowTitle(str(title))
|
|
743
|
+
msgBox.setText(traceback.format_exc())
|
|
744
|
+
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
745
|
+
msgBox.exec()
|
|
746
|
+
|
|
747
|
+
def on_click(self, event):
|
|
748
|
+
if self.debug: print('on_click')
|
|
749
|
+
self.x_moving_ref_left = event.xdata
|
|
750
|
+
self.y_moving_ref_left = event.ydata
|
|
751
|
+
self.signal_fig_on_click.emit(event)
|
|
752
|
+
|
|
753
|
+
def off_click(self, event):
|
|
754
|
+
if self.debug: print('off_click')
|
|
755
|
+
_x = event.xdata
|
|
756
|
+
_y = event.ydata
|
|
757
|
+
not_moved = ((self.x_moving_ref_left == _x) and (self.y_moving_ref_left == _y))
|
|
758
|
+
if not_moved:
|
|
759
|
+
self.signal_fig_click_no_drag.emit(event)
|
|
760
|
+
else:
|
|
761
|
+
self.signal_fig_click_drag.emit(event)
|
|
762
|
+
|
|
763
|
+
def reset(self):
|
|
764
|
+
self.ax.cla()
|
|
765
|
+
self.fig_ref = []
|
|
766
|
+
self.fig_ref_names = []
|
|
767
|
+
self.total_plot_n = 0
|
|
768
|
+
|
|
769
|
+
def plot_data(self, data):
|
|
770
|
+
self.reset()
|
|
771
|
+
|
|
772
|
+
self.data_x = data[:,0]
|
|
773
|
+
self.data_y = data[:,1]
|
|
774
|
+
|
|
775
|
+
self.ax.grid()
|
|
776
|
+
plot_label = 'Col_X 1 Col_Y 2'
|
|
777
|
+
ref, = self.ax.plot(self.data_x, self.data_y, '-o', label = plot_label)
|
|
778
|
+
self.total_plot_n+= 1
|
|
779
|
+
self.fig_ref.append(ref)
|
|
780
|
+
self.fig_ref_names.append(plot_label)
|
|
781
|
+
leg = self.ax.legend()
|
|
782
|
+
leg.set_draggable(True)
|
|
783
|
+
self.canvas.draw()
|
|
784
|
+
|
|
785
|
+
def delete_plot(self, element):
|
|
786
|
+
try:
|
|
787
|
+
if self.debug: print(f'pop {element}')
|
|
788
|
+
_ = self.fig_ref.pop(element)
|
|
789
|
+
_.remove()
|
|
790
|
+
self.fig_ref_names.pop(element)
|
|
791
|
+
leg = self.ax.legend()
|
|
792
|
+
leg.set_draggable(True)
|
|
793
|
+
self.autoscale_ax()
|
|
794
|
+
self.canvas.draw()
|
|
795
|
+
except Exception:
|
|
796
|
+
self.error_box('Frame_1_graph delete_plot')
|
|
797
|
+
|
|
798
|
+
def add_plot(self, data_x, data_y = None, plot_label = None):
|
|
799
|
+
if data_y is None:
|
|
800
|
+
data_y = data_x[:,1]
|
|
801
|
+
data_x = data_x[:,0]
|
|
802
|
+
i = self.total_plot_n
|
|
803
|
+
#plot_label = f'Plot {i}'
|
|
804
|
+
self.total_plot_n+= 1
|
|
805
|
+
ref, = self.ax.plot(data_x, data_y, '-o', label = plot_label)
|
|
806
|
+
self.fig_ref.append(ref)
|
|
807
|
+
self.fig_ref_names.append(plot_label)
|
|
808
|
+
|
|
809
|
+
leg = self.ax.legend()
|
|
810
|
+
leg.set_draggable(True)
|
|
811
|
+
self.autoscale_ax()
|
|
812
|
+
self.canvas.draw()
|
|
813
|
+
|
|
814
|
+
def autoscale_ax(self):
|
|
815
|
+
try:
|
|
816
|
+
border = 0.1
|
|
817
|
+
max_x = -np.inf
|
|
818
|
+
max_y = -np.inf
|
|
819
|
+
min_x = np.inf
|
|
820
|
+
min_y = np.inf
|
|
821
|
+
lines = self.ax.get_lines()
|
|
822
|
+
for line in lines:
|
|
823
|
+
x_data = line.get_xdata()
|
|
824
|
+
y_data = line.get_ydata()
|
|
825
|
+
max_x = max(max_x, x_data.max())
|
|
826
|
+
max_y = max(max_y, y_data.max())
|
|
827
|
+
min_x = min(min_x, x_data.min())
|
|
828
|
+
min_y = min(min_y, y_data.min())
|
|
829
|
+
|
|
830
|
+
border_x = (max_x - min_x)*border/2
|
|
831
|
+
border_y = (max_y - min_y)*border/2
|
|
832
|
+
self.ax.set_xlim(min_x-border_x, max_x+border_x)
|
|
833
|
+
self.ax.set_ylim(min_y-border_y, max_y+border_y)
|
|
834
|
+
except:
|
|
835
|
+
#No graph, do nothing
|
|
836
|
+
pass
|
|
837
|
+
|
|
838
|
+
def rescale_xy(self, event = None):
|
|
839
|
+
x_min = self.x_min_all
|
|
840
|
+
x_max = self.x_max_all
|
|
841
|
+
x_range = (x_max -x_min)*0.05*np.array((-1,1))+np.array((x_min,x_max))
|
|
842
|
+
self.ax_Spectro.set_xlim(x_range)
|
|
843
|
+
if self.debug: print('Rescale x')
|
|
844
|
+
y_min = self.intensities.min()
|
|
845
|
+
y_max = self.intensities.max()
|
|
846
|
+
y_range = (y_max -y_min)*0.05*np.array((-1,1))+np.array((y_min,y_max))
|
|
847
|
+
self.ax_Spectro.set_ylim(y_range)
|
|
848
|
+
if self.debug: print('Rescale y')
|
|
849
|
+
|
|
850
|
+
def rescale_x(self):
|
|
851
|
+
x_min = self.x_min_all
|
|
852
|
+
x_max = self.x_max_all
|
|
853
|
+
x_range = (x_max -x_min)*0.05*np.array((-1,1))+np.array((x_min,x_max))
|
|
854
|
+
self.ax_Spectro.set_xlim(x_range)
|
|
855
|
+
if self.debug: print('Rescale x')
|
|
856
|
+
|
|
857
|
+
def rescale_y(self):
|
|
858
|
+
y_min = self.y_min_all
|
|
859
|
+
y_max = self.y_max_all
|
|
860
|
+
y_range = (y_max -y_min)*0.05*np.array((-1,1))+np.array((y_min,y_max))
|
|
861
|
+
self.ax.set_ylim(y_range)
|
|
862
|
+
self.canvas.draw()
|
|
863
|
+
|
|
864
|
+
if __name__ == "__main__":
|
|
865
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
866
|
+
app.setStyleSheet("""
|
|
867
|
+
* {
|
|
868
|
+
font-size: 15px;
|
|
869
|
+
}
|
|
870
|
+
""")
|
|
871
|
+
#from OF_Model_11 import my_model
|
|
872
|
+
model = None
|
|
873
|
+
#window = Frame_1_graph(model)
|
|
874
|
+
#window = Fig_2_Commands(model)
|
|
875
|
+
#window = Fine_calib_Commands(model)
|
|
876
|
+
#window= Data_Table_Points(model)
|
|
877
|
+
#window = Frame_1_graph(model)
|
|
878
|
+
window = open_file_commands(model)
|
|
879
|
+
#window = show_text_file()
|
|
880
|
+
window.show()
|
|
881
|
+
sys.exit(app.exec())
|