dev: изменил создание виджета с графиками
This commit is contained in:
parent
c3d976f6a6
commit
3c7040692e
BIN
src - Ярлык.lnk
Normal file
BIN
src - Ярлык.lnk
Normal file
Binary file not shown.
Binary file not shown.
@ -45,18 +45,17 @@ class PlotWidget(BasePlotWidget):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _init_plot_widget(title: str) -> tuple[pg.PlotWidget, pg.LegendItem]:
|
||||
plot_widget = pg.PlotWidget(title=title)
|
||||
def _init_plot_item(title: str) -> tuple[pg.PlotItem, pg.LegendItem]:
|
||||
plot_item = pg.PlotItem(title=title)
|
||||
# Оптимизация отображения графиков
|
||||
plot_widget.setDownsampling(auto=True, mode='peak')
|
||||
plot_widget.showGrid(x=True, y=True)
|
||||
plot_widget.setClipToView(True)
|
||||
legend = pg.LegendItem((80, 60), offset=(70, 20))
|
||||
legend.setParentItem(plot_widget.graphicsItem())
|
||||
return plot_widget, legend
|
||||
plot_item.setDownsampling(auto=True, mode='peak')
|
||||
plot_item.showGrid(x=True, y=True)
|
||||
plot_item.setClipToView(True)
|
||||
legend = plot_item.addLegend(offset=(70, 20))
|
||||
return plot_item, legend
|
||||
|
||||
def _add_stage_regions(self,
|
||||
plot_widget: pg.PlotWidget,
|
||||
plot_item: pg.PlotItem,
|
||||
point_events: dict[str, list[float]],
|
||||
dataframe_headers: list[str],
|
||||
reg_items: dict,
|
||||
@ -71,12 +70,12 @@ class PlotWidget(BasePlotWidget):
|
||||
region = self._create_stage_region(stage, start_t, end_t, transparency)
|
||||
if region is not None:
|
||||
region.setZValue(-20)
|
||||
plot_widget.addItem(region)
|
||||
plot_item.addItem(region)
|
||||
reg_items["real"].setdefault(stage, [])
|
||||
reg_items["real"][stage].append(region)
|
||||
|
||||
def _add_ideal_stage_regions(self,
|
||||
plot_widget: pg.PlotWidget,
|
||||
plot_item: pg.PlotItem,
|
||||
ideal_data: dict[str, Any],
|
||||
point_events: dict[str, list[float]],
|
||||
reg_items: dict,
|
||||
@ -92,12 +91,12 @@ class PlotWidget(BasePlotWidget):
|
||||
region = self._create_stage_region(stage, start_t, end_t, transparency)
|
||||
if region:
|
||||
region.setZValue(-10)
|
||||
plot_widget.addItem(region)
|
||||
plot_item.addItem(region)
|
||||
reg_items["ideal"].setdefault(stage, [])
|
||||
reg_items["ideal"][stage].append(region)
|
||||
|
||||
def _add_ideal_signals(self,
|
||||
plot_widget: pg.PlotWidget,
|
||||
plot_item: pg.PlotItem,
|
||||
ideal_data: dict[str, Any],
|
||||
point_events: dict[str, list[float]],
|
||||
ideal_signals: list[dict[str, Any]],
|
||||
@ -115,13 +114,13 @@ class PlotWidget(BasePlotWidget):
|
||||
)
|
||||
if curve:
|
||||
curve.setZValue(10)
|
||||
plot_widget.addItem(curve)
|
||||
plot_item.addItem(curve)
|
||||
curve_items["ideal"].setdefault(signal["name"], {})
|
||||
curve_items["ideal"][signal["name"]].setdefault(stage, [])
|
||||
curve_items["ideal"][signal["name"]][stage].append(curve)
|
||||
|
||||
def _add_real_signals(self,
|
||||
plot_widget: pg.PlotWidget,
|
||||
plot_item: pg.PlotItem,
|
||||
dataframe: pd.DataFrame,
|
||||
real_signals: list[dict[str, Any]],
|
||||
legend: pg.LegendItem,
|
||||
@ -132,7 +131,7 @@ class PlotWidget(BasePlotWidget):
|
||||
dataframe_headers = dataframe.columns.tolist()
|
||||
for signal in real_signals:
|
||||
if signal["name"] in dataframe_headers:
|
||||
plot = plot_widget.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True)
|
||||
plot = plot_item.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True)
|
||||
plot.setZValue(0)
|
||||
legend.addItem(plot, signal["name"])
|
||||
curve_items["real"].setdefault(signal["name"], {})
|
||||
@ -163,8 +162,9 @@ class PlotWidget(BasePlotWidget):
|
||||
Собирает графический виджет для одного набора данных.
|
||||
Параметр `data` предполагается списком: [dataframe, points_pocket, useful_data].
|
||||
"""
|
||||
widget = QWidget()
|
||||
layout = QVBoxLayout(widget)
|
||||
result_widget = QWidget()
|
||||
result_layout = QVBoxLayout(result_widget)
|
||||
plot_layout = pg.GraphicsLayoutWidget()
|
||||
reg_items = {"real":{}, "ideal":{}}
|
||||
curve_items = {"real":{}, "ideal":{}}
|
||||
|
||||
@ -175,7 +175,7 @@ class PlotWidget(BasePlotWidget):
|
||||
dataframe_headers = dataframe.columns.tolist()
|
||||
|
||||
for widget_num, (channel, description) in enumerate(self._plt_channels.items()):
|
||||
plot_widget, legend = self._init_plot_widget(title=channel)
|
||||
plot_item, legend = self._init_plot_item(title=channel)
|
||||
settings = description["Settings"]
|
||||
|
||||
TWC_time = 0.0
|
||||
@ -184,7 +184,12 @@ class PlotWidget(BasePlotWidget):
|
||||
|
||||
# TODO: рассчитать корректный параметр range
|
||||
if settings["mirror ME"]:
|
||||
dataframe = self._mirror_shift_data("ME", description["Real_signals"], dataframe, range_ME)
|
||||
dataframe = self._mirror_shift_data(
|
||||
"ME",
|
||||
description["Real_signals"],
|
||||
dataframe,
|
||||
range_ME
|
||||
)
|
||||
|
||||
# Итерация по точкам
|
||||
for cur_point, point_data in enumerate(points_pocket):
|
||||
@ -207,7 +212,7 @@ class PlotWidget(BasePlotWidget):
|
||||
|
||||
# Добавляем реальные стадии
|
||||
if settings["stages"]:
|
||||
self._add_stage_regions(plot_widget, point_events, dataframe_headers, reg_items, 75)
|
||||
self._add_stage_regions(plot_item, point_events, dataframe_headers, reg_items, 75)
|
||||
|
||||
# TODO: подобрать не вырвеглазные цвета, возможно ограничить зону
|
||||
if settings["workpiece"]:
|
||||
@ -220,7 +225,7 @@ class PlotWidget(BasePlotWidget):
|
||||
rect_item.setZValue(-5)
|
||||
rect_item.setBrush(pg.mkBrush('grey'))
|
||||
rect_item.setPen(pg.mkPen('black', width=3))
|
||||
plot_widget.addItem(rect_item)
|
||||
plot_item.addItem(rect_item)
|
||||
|
||||
if settings["force accuracy"]:
|
||||
modifier = 0.05
|
||||
@ -235,12 +240,12 @@ class PlotWidget(BasePlotWidget):
|
||||
rect_item.setZValue(-5)
|
||||
rect_item.setBrush(pg.mkBrush((0,255,0, 50)))
|
||||
rect_item.setPen(pg.mkPen('black', width=0))
|
||||
plot_widget.addItem(rect_item)
|
||||
plot_item.addItem(rect_item)
|
||||
|
||||
# Добавляем идеальные стадии и идеальные сигналы
|
||||
if settings["ideals"]:
|
||||
self._add_ideal_stage_regions(plot_widget, ideal_data, point_events, reg_items, 100)
|
||||
self._add_ideal_signals(plot_widget, ideal_data, point_events, description["Ideal_signals"], curve_items)
|
||||
self._add_ideal_stage_regions(plot_item, ideal_data, point_events, reg_items, 100)
|
||||
self._add_ideal_signals(plot_item, ideal_data, point_events, description["Ideal_signals"], curve_items)
|
||||
|
||||
# Подсчёт производительности
|
||||
if settings["performance"]:
|
||||
@ -259,26 +264,26 @@ class PlotWidget(BasePlotWidget):
|
||||
worst_timeframe = point_timeframe
|
||||
|
||||
# Добавляем реальные сигналы
|
||||
self._add_real_signals(plot_widget, dataframe, description["Real_signals"], legend, curve_items)
|
||||
self._add_real_signals(plot_item, dataframe, description["Real_signals"], legend, curve_items)
|
||||
if widget_num == 0:
|
||||
main_plot = plot_widget
|
||||
main_plot = plot_item
|
||||
else:
|
||||
# Связываем остальные графики с основным графиком
|
||||
plot_widget.setXLink(main_plot)
|
||||
plot_item.setXLink(main_plot)
|
||||
|
||||
# Если есть настройка производительности, добавляем label
|
||||
if settings["performance"]:
|
||||
self._add_performance_label(layout, TWC_time, ideal_time, tesla_time)
|
||||
navigator, ROI_region = self._create_navigator(worst_timeframe, main_plot, dataframe, description["Real_signals"])
|
||||
self._add_performance_label(result_layout, TWC_time, ideal_time, tesla_time)
|
||||
|
||||
layout.addWidget(plot_widget)
|
||||
navigator, ROI_region = self._create_navigator(worst_timeframe, main_plot)
|
||||
|
||||
plot_layout.addItem(plot_item, widget_num, 0)
|
||||
|
||||
layout.addWidget(navigator)
|
||||
plot_layout.addItem(navigator, widget_num+1, 0)
|
||||
self._sync_main_plot_with_navigator(main_plot, ROI_region)
|
||||
main_plot.sigXRangeChanged.connect(lambda _, plot=main_plot, region=ROI_region: self._sync_navigator_with_main(main_plot=plot, region=region))
|
||||
|
||||
widget.setLayout(layout)
|
||||
return widget, reg_items, curve_items
|
||||
result_layout.addWidget(plot_layout)
|
||||
return result_widget, reg_items, curve_items
|
||||
|
||||
def build(self, data: list[list[Any]]) -> None:
|
||||
"""
|
||||
|
||||
Binary file not shown.
@ -240,27 +240,25 @@ class 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]:
|
||||
main_plot: pg.PlotItem) -> list[pg.PlotWidget, pg.LinearRegionItem]:
|
||||
"""
|
||||
Создаёт график-навигатор, отображающий все данные в уменьшенном масштабе.
|
||||
"""
|
||||
navigator = pg.PlotWidget(title="Navigator")
|
||||
navigator = pg.PlotItem(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"])
|
||||
# Получение кривых из main_plot
|
||||
for curve in main_plot.listDataItems():
|
||||
# Извлекаем данные из кривой
|
||||
x, y = curve.getData()
|
||||
curve_name = curve.opts.get("name", None)
|
||||
signal_pen = curve.opts.get("pen", None)
|
||||
x_downsampled, y_downsampled = self._downsample_data(x, y, max_points=1000)
|
||||
navigator.plot(x_downsampled, y_downsampled, pen=signal_pen, name=curve_name)
|
||||
|
||||
ROI_region = pg.LinearRegionItem(values=time_region, movable=True, brush=pg.mkBrush(0, 0, 255, 100), pen=pg.mkPen(width=4))
|
||||
ROI_region.setBounds([0, x.iloc[-1]])
|
||||
ROI_region.setBounds([0, x[-1]])
|
||||
navigator.addItem(ROI_region)
|
||||
navigator.getPlotItem().getViewBox().setLimits(xMin=0, xMax=x.iloc[-1])
|
||||
navigator.getViewBox().setLimits(xMin=0, xMax=x[-1])
|
||||
|
||||
# Связываем изменение региона навигатора с обновлением области просмотра основного графика
|
||||
ROI_region.sigRegionChanged.connect(lambda: self._sync_main_plot_with_navigator(main_plot, ROI_region))
|
||||
@ -268,7 +266,7 @@ class BasePlotWidget:
|
||||
return navigator, ROI_region
|
||||
|
||||
def _sync_main_plot_with_navigator(self,
|
||||
main_plot: pg.PlotWidget,
|
||||
main_plot: pg.PlotItem,
|
||||
region: pg.LinearRegionItem):
|
||||
"""
|
||||
Синхронизирует область просмотра основного графика с регионом навигатора.
|
||||
@ -301,7 +299,7 @@ class BasePlotWidget:
|
||||
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):
|
||||
def _sync_navigator_with_main(self, main_plot: pg.PlotItem, region:pg.LinearRegionItem):
|
||||
"""
|
||||
Синхронизирует регион навигатора с областью просмотра основного графика.
|
||||
"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user