chore: часть функций plotter перенесена в base
This commit is contained in:
parent
02268f1f7b
commit
365118bc22
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user