1
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2026-04-08 17:57:54 +02:00

Compare commits

..

6 Commits

Author SHA1 Message Date
semantic-release
ac868c80de 0.2.1
Automatically generated by python-semantic-release
2023-07-13 16:38:41 +00:00
947db1e0f3 fix: fixed setup config (wrong name) 2023-07-13 18:37:41 +02:00
86f4deffd8 fix: fixed bec_lib dependency 2023-07-13 18:33:58 +02:00
b5f7b4feee build: added black as dev dependency 2023-07-13 18:33:08 +02:00
f10de383a8 test: added tests for scan plot 2023-07-13 18:32:27 +02:00
4ee18ac3af refactor: added example usage within main statement 2023-07-13 18:32:10 +02:00
6 changed files with 122 additions and 50 deletions

View File

@@ -2,6 +2,13 @@
<!--next-version-placeholder-->
## v0.2.1 (2023-07-13)
### Fix
* Fixed setup config (wrong name) ([`947db1e`](https://gitlab.psi.ch/bec/bec-widgets/-/commit/947db1e0f32b067e67f94a7c8321da5194b1547b))
* Fixed bec_lib dependency ([`86f4def`](https://gitlab.psi.ch/bec/bec-widgets/-/commit/86f4deffd899111e8997010487ec54c6c62c43ab))
## v0.2.0 (2023-07-13)
### Feature

View File

@@ -2,12 +2,11 @@ from typing import List
import numpy as np
import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication, QGridLayout, QSizePolicy, QWidget
from pyqtgraph import mkPen
from pyqtgraph.Qt import QtCore
from pyqtgraph.Qt import QtCore, QtWidgets
class ConfigPlotter(QWidget):
class ConfigPlotter(pg.GraphicsWidget):
"""
ConfigPlotter is a widget that can be used to plot data from multiple channels
in a grid layout. The layout is specified by a list of dicts, where each dict
@@ -29,7 +28,7 @@ class ConfigPlotter(QWidget):
"""
def __init__(self, configs: List[dict], parent=None):
super(ConfigPlotter, self).__init__()
super().__init__(parent)
self.configs = configs
self.plots = {}
self._init_ui()
@@ -38,73 +37,63 @@ class ConfigPlotter(QWidget):
def _init_ui(self):
pg.setConfigOption("background", "w")
pg.setConfigOption("foreground", "k")
self.layout = QGridLayout()
self.setLayout(self.layout)
self.pen = mkPen(color=(56, 76, 107), width=4, style=QtCore.Qt.SolidLine)
self.show()
self.view = pg.GraphicsView()
self.view.setAntialiasing(True)
self.view.show()
self.layout = pg.GraphicsLayout()
self.view.setCentralWidget(self.layout)
def _init_plots(self):
for config in self.configs:
channels = config["config"]["channels"]
for channel in channels:
item = pg.PlotItem()
self.layout.addItem(
item,
row=config["y"],
col=config["x"],
rowspan=config["rows"],
colspan=config["cols"],
)
# call the corresponding init function, e.g. init_plotitem
init_func = getattr(self, f"init_{config['config']['item']}")
init_func(channel, config)
init_func(channel, config["config"], item)
# self.init_ImageItem(channel, config["config"], item)
def init_PlotItem(self, channel: str, config: dict):
def init_PlotItem(self, channel: str, config: dict, item: pg.GraphicsItem):
"""
Initialize a PlotItem
Args:
channel(str): channel to plot
config(dict): config dict for the channel
item(pg.GraphicsItem): PlotItem to plot the data
"""
# pylint: disable=invalid-name
plot_widget = pg.PlotWidget()
plot_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.layout.addWidget(plot_widget, config["y"], config["x"], config["rows"], config["cols"])
plot_data = plot_widget.plot(np.random.rand(100), pen=self.pen)
# item.setLabel("left", channel)
# self.plots[channel] = {"item": item, "plot_data": plot_data}
plot_data = item.plot(np.random.rand(100), pen=self.pen)
item.setLabel("left", channel)
self.plots[channel] = {"item": item, "plot_data": plot_data}
def init_ImageItem(self, channel: str, config: dict):
def init_ImageItem(self, channel: str, config: dict, item: pg.GraphicsItem):
"""
Initialize an ImageItem
Args:
channel(str): channel to plot
config(dict): config dict for the channel
item(pg.GraphicsItem): ImageItem to plot the data
"""
# pylint: disable=invalid-name
item = pg.PlotItem()
self.layout.addItem(
item,
row=config["y"],
col=config["x"],
rowspan=config["rows"],
colspan=config["cols"],
)
img = pg.ImageItem()
item.addItem(img)
img.setImage(np.random.rand(100, 100))
self.plots[channel] = {"item": item, "plot_data": img}
def init_ImageView(self, channel: str, config: dict):
"""
Initialize an ImageView
Args:
channel(str): channel to plot
config(dict): config dict for the channel
"""
# pylint: disable=invalid-name
img = pg.ImageView()
img.setImage(np.random.rand(100, 100))
self.layout.addWidget(img, config["y"], config["x"], config["rows"], config["cols"])
self.plots[channel] = {"item": img, "plot_data": img}
if __name__ == "__main__":
import sys
@@ -129,10 +118,10 @@ if __name__ == "__main__":
"rows": 2,
"y": 0,
"x": 1,
"config": {"channels": ["c"], "label_xy": ["", "c"], "item": "ImageView"},
"config": {"channels": ["c"], "label_xy": ["", "c"], "item": "ImageItem"},
},
]
app = QApplication(sys.argv)
app = QtWidgets.QApplication(sys.argv)
win = ConfigPlotter(CONFIG)
pg.exec()

View File

@@ -1,9 +1,8 @@
import itertools
import pyqtgraph as pg
from PyQt5.QtCore import pyqtProperty, pyqtSlot
from bec_lib.core.logger import bec_logger
from PyQt5.QtCore import pyqtProperty, pyqtSlot
logger = bec_logger.logger
@@ -104,3 +103,19 @@ class BECScanPlot(pg.PlotWidget):
@x_channel.setter
def x_channel(self, new_val):
self._x_channel = new_val
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
plot = BECScanPlot()
plot.y_channel_list = ["a", "b", "c"]
plot.initialize()
plot.show()
sys.exit(app.exec_())

View File

@@ -1,6 +1,6 @@
[metadata]
name = bec_lib
description = BEC library
name = bec_widgets
description = BEC Widgets
long_description = file: README.md
long_description_content_type = text/markdown
url = https://gitlab.psi.ch/bec/bec

View File

@@ -1,13 +1,10 @@
from setuptools import setup
__version__ = "0.2.0"
__version__ = "0.2.1"
if __name__ == "__main__":
setup(
install_requires=[
"pyqt5",
"pyqtgraph",
],
extras_require={"dev": ["pytest", "pytest-random-order", "coverage", "pytest-qt"]},
install_requires=["pyqt5", "pyqtgraph", "bec_lib"],
extras_require={"dev": ["pytest", "pytest-random-order", "coverage", "pytest-qt", "black"]},
version=__version__,
)

64
tests/test_scan_plot.py Normal file
View File

@@ -0,0 +1,64 @@
from pytestqt import qtbot
from bec_widgets import scan_plot
def test_scan_plot(qtbot):
"""Test ScanPlot"""
plot = scan_plot.BECScanPlot()
qtbot.addWidget(plot)
plot.show()
qtbot.waitForWindowShown(plot)
plot.x_channel = "x"
plot.y_channel_list = ["y1", "y2"]
plot.initialize()
plot.redraw_scan(
{"x": {"x": {"value": 1}}, "y1": {"y1": {"value": 1}}, "y2": {"y2": {"value": 3}}}
)
plot.redraw_scan(
{"x": {"x": {"value": 2}}, "y1": {"y1": {"value": 2}}, "y2": {"y2": {"value": 4}}}
)
assert all(plot.scan_curves["y1"].getData()[0] == [1, 2])
assert all(plot.scan_curves["y2"].getData()[1] == [3, 4])
def test_scan_plot_clears_data(qtbot):
"""Test ScanPlot"""
plot = scan_plot.BECScanPlot()
qtbot.addWidget(plot)
plot.show()
qtbot.waitForWindowShown(plot)
plot.x_channel = "x"
plot.y_channel_list = ["y1", "y2"]
plot.initialize()
plot.redraw_scan(
{"x": {"x": {"value": 1}}, "y1": {"y1": {"value": 1}}, "y2": {"y2": {"value": 3}}}
)
plot.clearData()
plot.redraw_scan(
{"x": {"x": {"value": 2}}, "y1": {"y1": {"value": 2}}, "y2": {"y2": {"value": 4}}}
)
assert all(plot.scan_curves["y1"].getData()[0] == [2])
assert all(plot.scan_curves["y2"].getData()[1] == [4])
def test_scan_plot_redraws_dap(qtbot):
"""Test ScanPlot"""
plot = scan_plot.BECScanPlot()
qtbot.addWidget(plot)
plot.show()
qtbot.waitForWindowShown(plot)
plot.y_channel_list = ["dap.y1", "dap.y2"]
plot.initialize()
plot.redraw_dap({"y1": {"x": [1], "y": [1]}, "y2": {"x": [2], "y": [2]}})
assert all(plot.dap_curves["y1"].getData()[0] == [1])
assert all(plot.dap_curves["y2"].getData()[1] == [2])