diff --git a/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc b/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc index 1dac748..de8f5fb 100644 Binary files a/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc and b/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc differ diff --git a/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc b/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc index 33a7e93..cc95fdd 100644 Binary files a/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc and b/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc differ diff --git a/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc b/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc index 01aa6e0..980cdcc 100644 Binary files a/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc and b/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc differ diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc index c93d105..f7576ab 100644 Binary files a/src/controller/__pycache__/controller.cpython-310.pyc and b/src/controller/__pycache__/controller.cpython-310.pyc differ diff --git a/src/controller/__pycache__/converter.cpython-310.pyc b/src/controller/__pycache__/converter.cpython-310.pyc index 6ae3490..58eb895 100644 Binary files a/src/controller/__pycache__/converter.cpython-310.pyc and b/src/controller/__pycache__/converter.cpython-310.pyc differ diff --git a/src/controller/__pycache__/mediator.cpython-310.pyc b/src/controller/__pycache__/mediator.cpython-310.pyc index e85d657..6717f3d 100644 Binary files a/src/controller/__pycache__/mediator.cpython-310.pyc and b/src/controller/__pycache__/mediator.cpython-310.pyc differ diff --git a/src/controller/__pycache__/monitor.cpython-310.pyc b/src/controller/__pycache__/monitor.cpython-310.pyc index b2d9573..c007b61 100644 Binary files a/src/controller/__pycache__/monitor.cpython-310.pyc and b/src/controller/__pycache__/monitor.cpython-310.pyc differ diff --git a/src/controller/__pycache__/passportFormer.cpython-310.pyc b/src/controller/__pycache__/passportFormer.cpython-310.pyc index 0447683..4bfe60a 100644 Binary files a/src/controller/__pycache__/passportFormer.cpython-310.pyc and b/src/controller/__pycache__/passportFormer.cpython-310.pyc differ diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index 8a61220..01f6071 100644 Binary files a/src/gui/__pycache__/mainGui.cpython-310.pyc and b/src/gui/__pycache__/mainGui.cpython-310.pyc differ diff --git a/src/gui/__pycache__/plotter.cpython-310.pyc b/src/gui/__pycache__/plotter.cpython-310.pyc index ec565ab..d4c52ba 100644 Binary files a/src/gui/__pycache__/plotter.cpython-310.pyc and b/src/gui/__pycache__/plotter.cpython-310.pyc differ diff --git a/src/gui/__pycache__/settings_window.cpython-310.pyc b/src/gui/__pycache__/settings_window.cpython-310.pyc index d6c61f4..0edf48f 100644 Binary files a/src/gui/__pycache__/settings_window.cpython-310.pyc and b/src/gui/__pycache__/settings_window.cpython-310.pyc differ diff --git a/src/gui/plotter.py b/src/gui/plotter.py index 8526ad5..29e99c5 100644 --- a/src/gui/plotter.py +++ b/src/gui/plotter.py @@ -1,8 +1,6 @@ import pandas as pd from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QGraphicsRectItem import copy - - import pyqtgraph as pg from typing import Optional, Any @@ -14,56 +12,6 @@ class ProcessStage(): finish_index:int class PlotWidget(BasePlotWidget): - - def _create_navigator(self, - time_region:tuple[float, float], - main_plot: pg.PlotWidget, - dataframe: pd.DataFrame, - real_signals: list[dict[str, Any]]) -> list[pg.PlotWidget, pg.LinearRegionItem]: - """ - Создаёт график-навигатор, отображающий все данные в уменьшенном масштабе. - """ - navigator = pg.PlotWidget(title="Navigator") - navigator.setFixedHeight(100) - - for signal in real_signals: - if signal["name"] in dataframe.columns: - x = dataframe["time"] - y = dataframe[signal["name"]] - - x_downsampled, y_downsampled = self._downsample_data(x, y, max_points=1000) - navigator.plot(x_downsampled, y_downsampled, pen=signal["pen"], name=signal["name"]) - - ROI_region = pg.LinearRegionItem(values=time_region, movable=True, brush=pg.mkBrush(0, 0, 255, 100)) - navigator.addItem(ROI_region) - - # Связываем изменение региона навигатора с обновлением области просмотра основного графика - ROI_region.sigRegionChanged.connect(lambda: self._sync_main_plot_with_navigator(main_plot, ROI_region)) - - return navigator, ROI_region - - def _downsample_data(self, x, y, max_points=5000): - """ - Понижает разрешение данных до заданного количества точек для улучшения производительности навигатора. - """ - if len(x) > max_points: - factor = len(x) // max_points - x_downsampled = x[::factor] - y_downsampled = y[::factor] - return x_downsampled, y_downsampled - return x, y - - def _sync_main_plot_with_navigator(self, - main_plot: pg.PlotWidget, - region: pg.LinearRegionItem): - """ - Синхронизирует область просмотра основного графика с регионом навигатора. - """ - x_min, x_max = region.getRegion() - if main_plot: - main_plot.blockSignals(True) - main_plot.setXRange(x_min, x_max, padding=0) - main_plot.blockSignals(False) def _create_curve_ideal(self, signal: dict[str, Any], @@ -197,29 +145,6 @@ class PlotWidget(BasePlotWidget): layout.addWidget(performance_label) performance_label.update() - def _mirror_shift_data(self, - valid_str: str, - signals: list[dict], - dataframe: pd.DataFrame, - shift: float) -> pd.DataFrame: - keys = dataframe.keys() - for signal in signals: - if valid_str in signal["name"] and signal["name"] in keys: - dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: shift-x) - return dataframe - - def _shift_data(self, - valid_str: str, - signals: list[dict], - dataframe: pd.DataFrame, - shift: float) -> pd.DataFrame: - keys = dataframe.keys() - for signal in signals: - if valid_str in signal["name"] and signal["name"] in keys: - dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: x + shift) - return dataframe - - def _build_widget(self, data: list[Any]) -> QWidget: """ Собирает графический виджет для одного набора данных. @@ -324,16 +249,6 @@ class PlotWidget(BasePlotWidget): widget.setLayout(layout) return widget - - def _sync_navigator_with_main(self, main_plot: pg.PlotWidget, region:pg.LinearRegionItem): - """ - Синхронизирует регион навигатора с областью просмотра основного графика. - """ - if region: - x_min, x_max = main_plot - region.blockSignals(True) # Предотвращаем рекурсию - region.setRegion([x_min, x_max]) - region.blockSignals(False) def build(self, data: list[list[Any]]) -> None: """ @@ -348,4 +263,3 @@ class PlotWidget(BasePlotWidget): widgets = [self._build_widget(data_sample) for data_sample in data] self._mediator.notify(self, widgets) - diff --git a/src/utils/base/__pycache__/base.cpython-310.pyc b/src/utils/base/__pycache__/base.cpython-310.pyc index b6502ba..5a76e8b 100644 Binary files a/src/utils/base/__pycache__/base.cpython-310.pyc and b/src/utils/base/__pycache__/base.cpython-310.pyc differ diff --git a/src/utils/base/base.py b/src/utils/base/base.py index 1029b54..8d499e6 100644 --- a/src/utils/base/base.py +++ b/src/utils/base/base.py @@ -9,10 +9,8 @@ from PyQt5.QtCore import QThread, QObject, QTimer from PyQt5.QtWidgets import QWidget, QTabWidget from PyQt5.QtOpenGL import QGLWidget from OptAlgorithm import OptAlgorithm -import pandas as pd -import pandas as pd import numpy as np - +import pyqtgraph as pg @@ -227,6 +225,88 @@ class BasePlotWidget: font-family: "Segoe UI", sans-serif; }""") + def _downsample_data(self, x, y, max_points=5000): + """ + Понижает разрешение данных до заданного количества точек для улучшения производительности навигатора. + """ + if len(x) > max_points: + factor = len(x) // max_points + x_downsampled = x[::factor] + y_downsampled = y[::factor] + return x_downsampled, y_downsampled + return x, y + + def _create_navigator(self, + time_region:tuple[float, float], + main_plot: pg.PlotWidget, + dataframe: pd.DataFrame, + real_signals: list[dict[str, Any]]) -> list[pg.PlotWidget, pg.LinearRegionItem]: + """ + Создаёт график-навигатор, отображающий все данные в уменьшенном масштабе. + """ + navigator = pg.PlotWidget(title="Navigator") + navigator.setFixedHeight(100) + + for signal in real_signals: + if signal["name"] in dataframe.columns: + x = dataframe["time"] + y = dataframe[signal["name"]] + + x_downsampled, y_downsampled = self._downsample_data(x, y, max_points=1000) + navigator.plot(x_downsampled, y_downsampled, pen=signal["pen"], name=signal["name"]) + + ROI_region = pg.LinearRegionItem(values=time_region, movable=True, brush=pg.mkBrush(0, 0, 255, 100)) + navigator.addItem(ROI_region) + + # Связываем изменение региона навигатора с обновлением области просмотра основного графика + ROI_region.sigRegionChanged.connect(lambda: self._sync_main_plot_with_navigator(main_plot, ROI_region)) + + return navigator, ROI_region + + def _sync_main_plot_with_navigator(self, + main_plot: pg.PlotWidget, + region: pg.LinearRegionItem): + """ + Синхронизирует область просмотра основного графика с регионом навигатора. + """ + x_min, x_max = region.getRegion() + if main_plot: + main_plot.blockSignals(True) + main_plot.setXRange(x_min, x_max, padding=0) + main_plot.blockSignals(False) + + def _mirror_shift_data(self, + valid_str: str, + signals: list[dict], + dataframe: pd.DataFrame, + shift: float) -> pd.DataFrame: + keys = dataframe.keys() + for signal in signals: + if valid_str in signal["name"] and signal["name"] in keys: + dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: shift-x) + return dataframe + + def _shift_data(self, + valid_str: str, + signals: list[dict], + dataframe: pd.DataFrame, + shift: float) -> pd.DataFrame: + keys = dataframe.keys() + for signal in signals: + if valid_str in signal["name"] and signal["name"] in keys: + dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: x + shift) + return dataframe + + def _sync_navigator_with_main(self, main_plot: pg.PlotWidget, region:pg.LinearRegionItem): + """ + Синхронизирует регион навигатора с областью просмотра основного графика. + """ + if region: + x_min, x_max = main_plot + region.blockSignals(True) # Предотвращаем рекурсию + region.setRegion([x_min, x_max]) + region.blockSignals(False) + @property def mediator(self) -> BaseMediator: return self._mediator