def __init__(self, data, parent=None): super().__init__(parent) self.setWindowTitle('Преобразование фурье') self.setMinimumSize(1200, 800) self.ampl_data = [data[0], data[1]] self.phase_data = [data[0], data[2]] #Виджет с графиком self.chart_view = ChartView() self.chart_view.setMinimumSize(1000, 800) #Виджет для коэффициентов fft_coef_list = QListWidget() fft_coef_label = QLabel('Коэффициенты фурье:') for elem in data[3]: str_elem = str(elem).replace('(', '') str_elem = str_elem.replace(')', '') fft_coef_list.addItem(str_elem) self.ampl_radio = QRadioButton() self.ampl_radio.setText('Амлитудный спектр') self.ampl_radio.toggled.connect(self.ampl_radio_toggled) self.phase_radio = QRadioButton() self.phase_radio.setText('Фазовый спектр') self.phase_radio.toggled.connect(self.phase_radio_toggled) #layout - groupBox for fft info group_box_layout = QVBoxLayout() group_box_layout.addWidget(self.ampl_radio) group_box_layout.addWidget(self.phase_radio) group_box_layout.addWidget(fft_coef_label) group_box_layout.addWidget(fft_coef_list) params_group_box = QGroupBox() params_group_box.setLayout(group_box_layout) layout = QVBoxLayout() child_layout = QHBoxLayout() layout.addLayout(child_layout) child_layout.addWidget(self.chart_view) child_layout.addWidget(params_group_box) self.setLayout(layout) self.ampl_radio.setChecked(True)
class PredictionsForm(QDialog): def __init__(self, data_analyzer: DataAnalyzer, train_size, predictions, parent=None): super().__init__(parent) self.data_analyzer = data_analyzer self.setWindowTitle('Графическое представление прогноза') self.setFixedSize(1000, 800) self.chart_view = ChartView() self.chart_view.x_time_scaled = True self.chart_view.x_name = 'Время' self.chart_view.y_name = self.data_analyzer.selected_column # self.chart_view.chart().legend().setBackgroundVisible(True) # self.chart_view.chart().legend().setPen(QPen(QColor(192, 192, 192, 192))) # self.chart_view.chart().legend().setAlignment(Qt.AlignBottom) ##Main layout main_layout = QVBoxLayout() main_layout.addWidget(self.chart_view) self.setLayout(main_layout) ##Построение графика #Получим необходимую колонку data = self.data_analyzer.get_selected_column() self.data_analyzer.set_data(data) x, y = DataAnalyzer.convert_data(self.data_analyzer.data) #Строим базовый график self.chart_view.build_plot((x, y), self.data_analyzer.rus_param_name, True, 'Original') #Конвертим предсказания и добавляем к графику for idx, pred in enumerate(predictions): pred_df = self.data_analyzer.predictions_to_timeseries(pred, train_size) pred_time_series = self.data_analyzer.convert_data(pred_df) self.chart_view.add_series(pred_time_series, 'Prediction ' + str(idx)) train_size += 1
def __init__(self, data_analyzer: DataAnalyzer, parent=None): super().__init__(parent) self.setWindowTitle('Окно настройки нейронной сети') self.setFixedSize(900, 650) self.future_prediction = False self.data_analyzer = data_analyzer self.nn_teacher = None self.predictions = list() ##NN Mode settings section gb_mode = QGroupBox('Выбор режима работы') gb_mode_l = QGridLayout() gb_mode.setLayout(gb_mode_l) #Single step self.rb_mode_single = QRadioButton() self.rb_mode_single.setChecked(True) grid_row = grid_add_label_widget(gb_mode_l, 'Один шаг', self.rb_mode_single, 0) #Windows mode self.rb_mode_window = QRadioButton() grid_row = grid_add_label_widget(gb_mode_l, 'Несколько шагов (окно)', self.rb_mode_window, grid_row) #Multi mode self.rb_mode_multi = QRadioButton() grid_row = grid_add_label_widget(gb_mode_l, 'Несколько шагов (стандарт)', self.rb_mode_multi, grid_row) ##NN settings section gb_settings = QGroupBox('Настройки нейронной сети') gb_settings_l = QGridLayout() # gb_settings_l.setColumnMinimumWidth(0, int(self.width() * 0.7)) gb_settings.setLayout(gb_settings_l) #Number of repeats field self.spin_repeat_num = QSpinBox() self.spin_repeat_num.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Количество повторов', self.spin_repeat_num, 0) #Number of epoch field self.spin_epoch_num = QSpinBox() self.spin_epoch_num.setMinimum(1) self.spin_epoch_num.setMaximum(10000) grid_row = grid_add_label_widget(gb_settings_l, 'Количество поколений', self.spin_epoch_num, grid_row) #Number of neurons field self.spin_neuron_num = QSpinBox() self.spin_neuron_num.setMinimum(1) self.spin_neuron_num.setMaximum(250) grid_row = grid_add_label_widget(gb_settings_l, 'Количество нейронов в слое LSTM', self.spin_neuron_num, grid_row) #Number of layers self.spin_layers_num = QSpinBox() self.spin_layers_num.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Количество скрытых слоев', self.spin_layers_num, grid_row) #Batch size field self.spin_batch_size = QSpinBox() self.spin_batch_size.setMinimum(1) self.spin_batch_size.setMaximum(10000) grid_row = grid_add_label_widget(gb_settings_l, 'Размер партии (batch size)', self.spin_batch_size, grid_row) #Size of train series self.spin_train_size = QSpinBox() self.spin_train_size.setMinimum(1) self.spin_train_size.setMaximum(self.data_analyzer.get_data_len()) grid_row = grid_add_label_widget(gb_settings_l, 'Объем обучающей выборки', self.spin_train_size, grid_row) #Size of input vector self.spin_input_vec_size = QSpinBox() self.spin_input_vec_size.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Размерность входного вектора', self.spin_input_vec_size, grid_row) #Size of output vector self.spin_output_vec_size = QSpinBox() self.spin_output_vec_size.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Размерность выходного вектора', self.spin_output_vec_size, grid_row) self.combo_optimizer = QComboBox() self.combo_optimizer.addItem("sgd") self.combo_optimizer.addItem("adam") grid_add_label_widget(gb_settings_l, 'Метод оптимизации', self.combo_optimizer, grid_row) ##NN report settings gb_report = QGroupBox('Отчет о работе сети') gb_report_l = QGridLayout() # gb_report_l.setColumnMinimumWidth(0, int(self.width() * 0.7)) gb_report.setLayout(gb_report_l) #Current epoch self.r_current_epoch = QLineEdit('0') self.r_current_epoch.setReadOnly(True) grid_row = grid_add_label_widget(gb_report_l, 'Номер текущего поколения', self.r_current_epoch, 0) #Current repeat self.r_current_repeat = QLineEdit('0') self.r_current_repeat.setReadOnly(True) grid_row = grid_add_label_widget(gb_report_l, 'Номер текущего повтора', self.r_current_repeat, grid_row) ##NN Control buttons buttons_layout = QHBoxLayout() self.b_start = QPushButton('Начать обучение') self.b_start.clicked.connect(self.nn_start_education) self.b_stop = QPushButton('Остановить обучение') self.b_stop.clicked.connect(self.nn_stop_education) self.b_stop.setEnabled(False) buttons_layout.addWidget(self.b_stop) buttons_layout.addWidget(self.b_start) ##NN Report controls self.chart_view = ChartView(True) #No margins enabled self.chart_view.setFixedSize(450, 250) self.chart_view.x_name = "Повтор" self.chart_view.y_name = "RMSE" self.chart_view.x_tick_num = 10 self.chart_view.y_tick_num = 5 self.chart_view.x_label_angle = 0 self.chart_view.y_label_angle = 0 self.chart_view.x_min = 1 self.chart_view.x_max = 2 self.chart_view.build_plot(None, None) self.predictions_table = QTableWidget(self) self.predictions_table.setColumnCount(3) self.predictions_table.setColumnWidth(1, 200) self.predictions_table.setHorizontalHeaderLabels( ['RMSE', 'Predict', 'Time']) self.predictions_table.horizontalHeader().setStretchLastSection(True) self.predictions_table.setEditTriggers(QTableWidget.NoEditTriggers) self.predictions_table.cellDoubleClicked.connect( self.predictions_build_plot) gb_rmse_report = QGroupBox('Отчет об RMSE') gb_rmse_layout = QHBoxLayout() gb_rmse_report.setLayout(gb_rmse_layout) lb_rmse_titile = QLabel('Среднее RMSE:') self.avg_rmse_value = QLabel() gb_rmse_layout.addWidget(lb_rmse_titile) gb_rmse_layout.addWidget(self.avg_rmse_value) #Main layout main_layout = QGridLayout() main_layout.addWidget(gb_mode, 0, 0) main_layout.addWidget(gb_settings, 1, 0) main_layout.addWidget(gb_report, 2, 0) main_layout.addWidget(self.chart_view, 0, 1) main_layout.addWidget(self.predictions_table, 1, 1) main_layout.addWidget(gb_rmse_report, 2, 1) main_layout.addLayout(buttons_layout, 3, 0, 1, 2) self.setLayout(main_layout)
class NeuralNetworkDialog(QDialog): def __init__(self, data_analyzer: DataAnalyzer, parent=None): super().__init__(parent) self.setWindowTitle('Окно настройки нейронной сети') self.setFixedSize(900, 650) self.future_prediction = False self.data_analyzer = data_analyzer self.nn_teacher = None self.predictions = list() ##NN Mode settings section gb_mode = QGroupBox('Выбор режима работы') gb_mode_l = QGridLayout() gb_mode.setLayout(gb_mode_l) #Single step self.rb_mode_single = QRadioButton() self.rb_mode_single.setChecked(True) grid_row = grid_add_label_widget(gb_mode_l, 'Один шаг', self.rb_mode_single, 0) #Windows mode self.rb_mode_window = QRadioButton() grid_row = grid_add_label_widget(gb_mode_l, 'Несколько шагов (окно)', self.rb_mode_window, grid_row) #Multi mode self.rb_mode_multi = QRadioButton() grid_row = grid_add_label_widget(gb_mode_l, 'Несколько шагов (стандарт)', self.rb_mode_multi, grid_row) ##NN settings section gb_settings = QGroupBox('Настройки нейронной сети') gb_settings_l = QGridLayout() # gb_settings_l.setColumnMinimumWidth(0, int(self.width() * 0.7)) gb_settings.setLayout(gb_settings_l) #Number of repeats field self.spin_repeat_num = QSpinBox() self.spin_repeat_num.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Количество повторов', self.spin_repeat_num, 0) #Number of epoch field self.spin_epoch_num = QSpinBox() self.spin_epoch_num.setMinimum(1) self.spin_epoch_num.setMaximum(10000) grid_row = grid_add_label_widget(gb_settings_l, 'Количество поколений', self.spin_epoch_num, grid_row) #Number of neurons field self.spin_neuron_num = QSpinBox() self.spin_neuron_num.setMinimum(1) self.spin_neuron_num.setMaximum(250) grid_row = grid_add_label_widget(gb_settings_l, 'Количество нейронов в слое LSTM', self.spin_neuron_num, grid_row) #Number of layers self.spin_layers_num = QSpinBox() self.spin_layers_num.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Количество скрытых слоев', self.spin_layers_num, grid_row) #Batch size field self.spin_batch_size = QSpinBox() self.spin_batch_size.setMinimum(1) self.spin_batch_size.setMaximum(10000) grid_row = grid_add_label_widget(gb_settings_l, 'Размер партии (batch size)', self.spin_batch_size, grid_row) #Size of train series self.spin_train_size = QSpinBox() self.spin_train_size.setMinimum(1) self.spin_train_size.setMaximum(self.data_analyzer.get_data_len()) grid_row = grid_add_label_widget(gb_settings_l, 'Объем обучающей выборки', self.spin_train_size, grid_row) #Size of input vector self.spin_input_vec_size = QSpinBox() self.spin_input_vec_size.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Размерность входного вектора', self.spin_input_vec_size, grid_row) #Size of output vector self.spin_output_vec_size = QSpinBox() self.spin_output_vec_size.setMinimum(1) grid_row = grid_add_label_widget(gb_settings_l, 'Размерность выходного вектора', self.spin_output_vec_size, grid_row) self.combo_optimizer = QComboBox() self.combo_optimizer.addItem("sgd") self.combo_optimizer.addItem("adam") grid_add_label_widget(gb_settings_l, 'Метод оптимизации', self.combo_optimizer, grid_row) ##NN report settings gb_report = QGroupBox('Отчет о работе сети') gb_report_l = QGridLayout() # gb_report_l.setColumnMinimumWidth(0, int(self.width() * 0.7)) gb_report.setLayout(gb_report_l) #Current epoch self.r_current_epoch = QLineEdit('0') self.r_current_epoch.setReadOnly(True) grid_row = grid_add_label_widget(gb_report_l, 'Номер текущего поколения', self.r_current_epoch, 0) #Current repeat self.r_current_repeat = QLineEdit('0') self.r_current_repeat.setReadOnly(True) grid_row = grid_add_label_widget(gb_report_l, 'Номер текущего повтора', self.r_current_repeat, grid_row) ##NN Control buttons buttons_layout = QHBoxLayout() self.b_start = QPushButton('Начать обучение') self.b_start.clicked.connect(self.nn_start_education) self.b_stop = QPushButton('Остановить обучение') self.b_stop.clicked.connect(self.nn_stop_education) self.b_stop.setEnabled(False) buttons_layout.addWidget(self.b_stop) buttons_layout.addWidget(self.b_start) ##NN Report controls self.chart_view = ChartView(True) #No margins enabled self.chart_view.setFixedSize(450, 250) self.chart_view.x_name = "Повтор" self.chart_view.y_name = "RMSE" self.chart_view.x_tick_num = 10 self.chart_view.y_tick_num = 5 self.chart_view.x_label_angle = 0 self.chart_view.y_label_angle = 0 self.chart_view.x_min = 1 self.chart_view.x_max = 2 self.chart_view.build_plot(None, None) self.predictions_table = QTableWidget(self) self.predictions_table.setColumnCount(3) self.predictions_table.setColumnWidth(1, 200) self.predictions_table.setHorizontalHeaderLabels( ['RMSE', 'Predict', 'Time']) self.predictions_table.horizontalHeader().setStretchLastSection(True) self.predictions_table.setEditTriggers(QTableWidget.NoEditTriggers) self.predictions_table.cellDoubleClicked.connect( self.predictions_build_plot) gb_rmse_report = QGroupBox('Отчет об RMSE') gb_rmse_layout = QHBoxLayout() gb_rmse_report.setLayout(gb_rmse_layout) lb_rmse_titile = QLabel('Среднее RMSE:') self.avg_rmse_value = QLabel() gb_rmse_layout.addWidget(lb_rmse_titile) gb_rmse_layout.addWidget(self.avg_rmse_value) #Main layout main_layout = QGridLayout() main_layout.addWidget(gb_mode, 0, 0) main_layout.addWidget(gb_settings, 1, 0) main_layout.addWidget(gb_report, 2, 0) main_layout.addWidget(self.chart_view, 0, 1) main_layout.addWidget(self.predictions_table, 1, 1) main_layout.addWidget(gb_rmse_report, 2, 1) main_layout.addLayout(buttons_layout, 3, 0, 1, 2) self.setLayout(main_layout) def nn_start_education(self): self.clean_report() self.chart_view.clean() self.set_cbuttons_state(False) self.set_spins_state(False) #Pick future forecast if train_size == series_size if self.spin_train_size.value() == self.data_analyzer.get_data_len(): self.future_prediction = True else: self.future_prediction = False if self.rb_mode_single.isChecked(): nn = NSingleStep(self.data_analyzer.data, self.spin_train_size.value(), self.spin_repeat_num.value(), self.spin_epoch_num.value(), self.spin_batch_size.value(), self.spin_neuron_num.value(), self.spin_layers_num.value(), self.combo_optimizer.currentText()) elif self.rb_mode_window.isChecked(): nn = NMultiWindowMode(self.data_analyzer.data, self.spin_train_size.value(), self.spin_repeat_num.value(), self.spin_epoch_num.value(), self.spin_batch_size.value(), self.spin_neuron_num.value(), self.spin_layers_num.value(), self.combo_optimizer.currentText(), 10) else: nn = NMultiStep(self.data_analyzer.data, self.spin_train_size.value(), self.spin_repeat_num.value(), self.spin_epoch_num.value(), self.spin_input_vec_size.value(), self.spin_output_vec_size.value(), self.spin_batch_size.value(), self.spin_neuron_num.value(), self.spin_layers_num.value(), self.combo_optimizer.currentText()) self.nn_teacher = NeuralNetworkTeacher(nn, self) self.nn_teacher.signal_epoch.connect(self.increment_epoch) self.nn_teacher.signal_repeat.connect(self.increment_repeats) self.nn_teacher.signal_complete.connect(self.teaching_complete) self.nn_teacher.start() def nn_stop_education(self): QGuiApplication.setOverrideCursor(Qt.WaitCursor) if self.nn_teacher: self.nn_teacher.tterminate() if self.nn_teacher.wait(10000): QGuiApplication.setOverrideCursor(Qt.ArrowCursor) self.set_cbuttons_state(True) self.set_spins_state(True) else: QGuiApplication.setOverrideCursor(Qt.ArrowCursor) show_msgbox( 'Ошибка при остановке обучения, перезапустите программу!', True) def increment_epoch(self, count): self.r_current_epoch.setText(str(count + 1)) def increment_repeats(self, count, predictions: Predictions): self.r_current_repeat.setText(str(count + 1)) if not self.future_prediction: self.chart_view.series_append( count + 1, predictions.rmse[0], 1, self.get_min_rmse(), True, predictions.rmse[0] > self.get_max_rmse()) self.predictions.append(predictions) #Add result in prediction_table row_num = self.predictions_table.rowCount() if self.rb_mode_multi.isChecked(): predictions_str = '' for pred in predictions.values: predictions_str = predictions_str + '[' + ', '.join( str(round(e, 4)) for e in pred) + '] ' else: predictions_str = ', '.join( str(round(e, 4)) for e in predictions.values) self.predictions_table.insertRow(row_num) rmse_str = ', '.join(str(round(e, 4)) for e in predictions.rmse) r_item = QTableWidgetItem(rmse_str) p_item = QTableWidgetItem(predictions_str) t_item = QTableWidgetItem(str(round(predictions.train_time, 1))) self.predictions_table.setItem(row_num, 0, r_item) self.predictions_table.setItem(row_num, 1, p_item) self.predictions_table.setItem(row_num, 2, t_item) def predictions_build_plot(self, row, column): predictions = list() if not self.rb_mode_multi.isChecked(): predictions.append(self.predictions[row].values) else: predictions = self.predictions[row].values predictions_form = PredictionsForm(self.data_analyzer, self.spin_train_size.value(), predictions, self) predictions_form.exec() def teaching_complete(self): rmse_matrix = list() for pred in self.predictions: rmse_matrix.append(pred.rmse) rmse_matrix = np.array(rmse_matrix) avg_rmse = rmse_matrix.mean(axis=0) avg_rmse_str = ', '.join(str(round(avg_rm, 4)) for avg_rm in avg_rmse) self.avg_rmse_value.setText(avg_rmse_str) self.set_cbuttons_state(True) self.set_spins_state(True) def set_spins_state(self, state): self.spin_batch_size.setEnabled(state) self.spin_neuron_num.setEnabled(state) self.spin_epoch_num.setEnabled(state) self.spin_repeat_num.setEnabled(state) self.spin_train_size.setEnabled(state) self.spin_input_vec_size.setEnabled(state) self.spin_output_vec_size.setEnabled(state) self.spin_layers_num.setEnabled(state) self.combo_optimizer.setEnabled(state) def clean_report(self): self.r_current_epoch.setText('0') self.r_current_repeat.setText('0') self.predictions.clear() self.predictions_table.clear() self.predictions_table.setRowCount(0) def set_cbuttons_state(self, state): self.b_start.setEnabled(state) self.b_stop.setEnabled(not state) def get_max_rmse(self): max_rmse = 0 for pred in self.predictions: if pred.rmse[0] > max_rmse: max_rmse = pred.rmse[0] return max_rmse def get_min_rmse(self): if len(self.predictions) == 0: return 0 min_rmse = sys.float_info.max for pred in self.predictions: if pred.rmse[0] < min_rmse: min_rmse = pred.rmse[0] return min_rmse
def __init__(self, data_analyzer: DataAnalyzer, parent=None): super().__init__(parent) self.setWindowTitle('Окно графиков') self.setMinimumSize(1200, 800) self.data_analyzer = data_analyzer self.chart_view = ChartView() self.chart_view.x_time_scaled = True self.chart_view.setMinimumSize(1000, 800) # ================ # Разметка виджета # ================ #Словарь для хранения лейблов со значениеями статистических характеристик self.param_label_container = {} #Список параметров для построения self.combo_headers = QComboBox() #Кнопка для построения Преобр. Фурье fft_plot_button = QPushButton() fft_plot_button.setText('Преобразование Фурье') fft_plot_button.clicked.connect(self.fft_build_plot_clicked) #Кнопка для вызова окна Нейронной сети neural_button = QPushButton() neural_button.setText('Окно обучения нейронной сети') neural_button.clicked.connect(self.neural_button_click) #layout - groupbox for measure info (station id, detector SN) measure_info_layout = QVBoxLayout() station_lb = QLabel('Номер станции: ' + str(data_analyzer.station)) sn_lb = QLabel('Серийный номер датчика: ' + data_analyzer.detector) measure_info_layout.addWidget(station_lb) measure_info_layout.addWidget(sn_lb) group_box_info = QGroupBox() group_box_info.setTitle('Основная информация об измерении') group_box_info.setLayout(measure_info_layout) #layout - group box for settings plot widgets plot_controls_layout = QVBoxLayout() plot_controls_layout.addWidget(self.combo_headers, 0, Qt.AlignTop) plot_controls_layout.addWidget(fft_plot_button, 0, Qt.AlignTop) plot_controls_layout.addWidget(neural_button, 0, Qt.AlignTop) group_box_plot = QGroupBox() group_box_plot.setLayout(plot_controls_layout) group_box_plot.setTitle('Параметры построения графика') #layout - labels with param name and value params_layout = QGridLayout() self.add_statistics_parm('Минимальное значение', params_layout) self.add_statistics_parm('Максимальное значение', params_layout) self.add_statistics_parm('Мат. ожидание', params_layout) self.add_statistics_parm('Дисперсия', params_layout) self.add_statistics_parm('Медиана', params_layout) self.add_statistics_parm('Мода', params_layout) self.add_statistics_parm('Размах', params_layout) #Статистические параметры group_box_param = QGroupBox() group_box_param.setTitle('Статистические характеристики') group_box_param.setLayout(params_layout) #layout - для всех настроек all_param_layout = QVBoxLayout() all_param_layout.addWidget(group_box_info) all_param_layout.addWidget(group_box_plot) all_param_layout.addWidget(group_box_param) #layout - Дочерний слой основного слоя layout = QGridLayout() layout.addWidget(self.chart_view, 0, 0) layout.addLayout(all_param_layout, 0, 1, Qt.AlignTop) #layout - Основной слой main_layout = QVBoxLayout() main_layout.addLayout(layout) self.setLayout(main_layout) #Сигнал о изменении текста comboBox с заголовками данных self.combo_headers.currentTextChanged.connect(self.buildplot) #Заполним comboBox for header in data_analyzer.get_headers(): self.combo_headers.addItem(header) # ============= # Создание меню # ============= menu_bar = QMenuBar() file_menu = menu_bar.addMenu('Файл') export_data_action = QAction('Экспортировать данные', self) export_data_action.triggered.connect(self.export_data) file_menu.addAction(export_data_action) main_layout.setMenuBar(menu_bar)
class GraphicWindow(QDialog): def __init__(self, data_analyzer: DataAnalyzer, parent=None): super().__init__(parent) self.setWindowTitle('Окно графиков') self.setMinimumSize(1200, 800) self.data_analyzer = data_analyzer self.chart_view = ChartView() self.chart_view.x_time_scaled = True self.chart_view.setMinimumSize(1000, 800) # ================ # Разметка виджета # ================ #Словарь для хранения лейблов со значениеями статистических характеристик self.param_label_container = {} #Список параметров для построения self.combo_headers = QComboBox() #Кнопка для построения Преобр. Фурье fft_plot_button = QPushButton() fft_plot_button.setText('Преобразование Фурье') fft_plot_button.clicked.connect(self.fft_build_plot_clicked) #Кнопка для вызова окна Нейронной сети neural_button = QPushButton() neural_button.setText('Окно обучения нейронной сети') neural_button.clicked.connect(self.neural_button_click) #layout - groupbox for measure info (station id, detector SN) measure_info_layout = QVBoxLayout() station_lb = QLabel('Номер станции: ' + str(data_analyzer.station)) sn_lb = QLabel('Серийный номер датчика: ' + data_analyzer.detector) measure_info_layout.addWidget(station_lb) measure_info_layout.addWidget(sn_lb) group_box_info = QGroupBox() group_box_info.setTitle('Основная информация об измерении') group_box_info.setLayout(measure_info_layout) #layout - group box for settings plot widgets plot_controls_layout = QVBoxLayout() plot_controls_layout.addWidget(self.combo_headers, 0, Qt.AlignTop) plot_controls_layout.addWidget(fft_plot_button, 0, Qt.AlignTop) plot_controls_layout.addWidget(neural_button, 0, Qt.AlignTop) group_box_plot = QGroupBox() group_box_plot.setLayout(plot_controls_layout) group_box_plot.setTitle('Параметры построения графика') #layout - labels with param name and value params_layout = QGridLayout() self.add_statistics_parm('Минимальное значение', params_layout) self.add_statistics_parm('Максимальное значение', params_layout) self.add_statistics_parm('Мат. ожидание', params_layout) self.add_statistics_parm('Дисперсия', params_layout) self.add_statistics_parm('Медиана', params_layout) self.add_statistics_parm('Мода', params_layout) self.add_statistics_parm('Размах', params_layout) #Статистические параметры group_box_param = QGroupBox() group_box_param.setTitle('Статистические характеристики') group_box_param.setLayout(params_layout) #layout - для всех настроек all_param_layout = QVBoxLayout() all_param_layout.addWidget(group_box_info) all_param_layout.addWidget(group_box_plot) all_param_layout.addWidget(group_box_param) #layout - Дочерний слой основного слоя layout = QGridLayout() layout.addWidget(self.chart_view, 0, 0) layout.addLayout(all_param_layout, 0, 1, Qt.AlignTop) #layout - Основной слой main_layout = QVBoxLayout() main_layout.addLayout(layout) self.setLayout(main_layout) #Сигнал о изменении текста comboBox с заголовками данных self.combo_headers.currentTextChanged.connect(self.buildplot) #Заполним comboBox for header in data_analyzer.get_headers(): self.combo_headers.addItem(header) # ============= # Создание меню # ============= menu_bar = QMenuBar() file_menu = menu_bar.addMenu('Файл') export_data_action = QAction('Экспортировать данные', self) export_data_action.triggered.connect(self.export_data) file_menu.addAction(export_data_action) main_layout.setMenuBar(menu_bar) #Create set of labels (name - value of param) and add it on layout def add_statistics_parm(self, name, layout: QGridLayout): param_label = QLabel() param_label.setText(name + ':') param_value_label = QLabel() #Номер последнего параметра в списке self.param_label_container[name] = param_value_label numofparam = len(self.param_label_container) layout.addWidget(param_label, numofparam - 1, 0) layout.addWidget(param_value_label, numofparam - 1, 1) def buildplot(self, header_name): #Получим необходимую колонку data = self.data_analyzer.get_column(header_name) #Занесем данные в анализатор self.data_analyzer.set_data(data) #Конвертируем в удобный вид x, y = DataAnalyzer.convert_data(self.data_analyzer.data) self.chart_view.y_name = header_name self.chart_view.y_min = float(self.data_analyzer.min() - 0.1) self.chart_view.y_max = float(self.data_analyzer.max() + 0.1) self.chart_view.build_plot((x, y), self.data_analyzer.rus_param_name) #Заполним параметры self.fill_params() def fill_params(self): self.param_label_container['Минимальное значение'].setText( str(self.data_analyzer.min())) self.param_label_container['Максимальное значение'].setText( str(self.data_analyzer.max())) self.param_label_container['Мат. ожидание'].setText( str(self.data_analyzer.mean())) self.param_label_container['Дисперсия'].setText( str(self.data_analyzer.std())) self.param_label_container['Медиана'].setText( str(self.data_analyzer.median())) self.param_label_container['Мода'].setText( str(self.data_analyzer.mode())) self.param_label_container['Размах'].setText( str(self.data_analyzer.min_max_delta())) def fft_build_plot_clicked(self): fft_dlg = FftDialog(self.data_analyzer.fft()) fft_dlg.exec() def neural_button_click(self): nn_dlg = NeuralNetworkDialog(self.data_analyzer, self) nn_dlg.exec() def export_data(self): file_name = QFileDialog.getSaveFileName( self, 'Save file', None, "CSV (*.csv);;Excel (*.xlsx)")[0] if file_name: export_result = self.data_analyzer.export(file_name) if export_result == 0: helper.show_msgbox( 'Расширение файла для экспорта не указано, экспорт отменен!' ) elif export_result == -1: helper.show_msgbox( 'Указано неподдерживаемое расширение файла для экспорта, экспорт отменен!' )