在 PlotWidget 中添加自定义标签

Posted

技术标签:

【中文标题】在 PlotWidget 中添加自定义标签【英文标题】:Add custom label inside PlotWidget 【发布时间】:2021-02-25 01:21:23 【问题描述】:

我正在尝试在绘图的右上角添加一个标签,以显示最新的数据值。我尝试使用pg.LabelItem 并将其添加到pg.PlotWidget 并在每次新数据更新时更新标签,但我无法让标签出现。这是我正在尝试做的一些图片:

我有什么:

我想要做什么:

我无法让白色标签出现在情节上。这是我的代码:

from PyQt4 import QtCore, QtGui
from threading import Thread
import pyqtgraph as pg
import numpy as np
import random
import sys
import time

class SimplePlot(QtGui.QWidget):
    def __init__(self, parent=None):
        super(SimplePlot, self).__init__(parent)
        
        # Desired Frequency (Hz) = 1 / self.FREQUENCY
        # USE FOR TIME.SLEEP (s)
        self.FREQUENCY = .004

        # Frequency to update plot (ms)
        # USE FOR TIMER.TIMER (ms)
        self.TIMER_FREQUENCY = self.FREQUENCY * 1000

        # Set X Axis range. If desired is [-10,0] then set LEFT_X = -10 and RIGHT_X = 0
        self.LEFT_X = -10
        self.RIGHT_X = 0
        self.X_Axis = np.arange(self.LEFT_X, self.RIGHT_X, self.FREQUENCY)
        self.buffer = int((abs(self.LEFT_X) + abs(self.RIGHT_X))/self.FREQUENCY)
        self.data = [] 

        # Create Plot Widget 
        self.simple_plot_widget = pg.PlotWidget()

        # Enable/disable plot squeeze (Fixed axis movement)
        self.simple_plot_widget.plotItem.setMouseEnabled(x=False, y=False)
        self.simple_plot_widget.setXRange(self.LEFT_X, self.RIGHT_X)
        self.simple_plot_widget.setTitle('Plot')
        self.simple_plot_widget.setLabel('left', 'Value')
        self.simple_plot_widget.setLabel('bottom', 'Time (s)')
        
        self.simple_plot = self.simple_plot_widget.plot()
        self.simple_plot.setPen(197,235,255)

        self.label_value = pg.LabelItem('', **'color': '#FFF')
        self.simple_plot_widget.addItem(self.label_value)

        self.layout = QtGui.QGridLayout()
        self.layout.addWidget(self.simple_plot_widget)

        self.read_position_thread()
        self.start()
                
    # Update plot
    def start(self):
        self.position_update_timer = QtCore.QTimer()
        self.position_update_timer.timeout.connect(self.plot_updater)
        self.position_update_timer.start(self.get_simple_plot_timer_frequency())
    
    # Read in data using a thread
    def read_position_thread(self):
        self.current_position_value = 0
        self.old_current_position_value = 0
        self.position_update_thread = Thread(target=self.read_position, args=())
        self.position_update_thread.daemon = True
        self.position_update_thread.start()

    def read_position(self):
        frequency = self.get_simple_plot_frequency()
        while True:
            try:
                # Add data
                self.current_position_value = self.current_position_value + random.uniform(-1, -5)
                self.old_current_position_value = self.current_position_value
                time.sleep(frequency)
            except:
                self.current_position_value = self.old_current_position_value

    def plot_updater(self):
        self.dataPoint = float(self.current_position_value)

        if len(self.data) >= self.buffer:
            del self.data[:1]
        self.data.append(self.dataPoint)
        self.simple_plot.setData(self.X_Axis[len(self.X_Axis) - len(self.data):], self.data)

        # Update label value
        self.label_value.setText(str(self.dataPoint))

    def clear_simple_plot(self):
        self.data[:] = []

    def get_simple_plot_frequency(self):
        return self.FREQUENCY
    
    def get_simple_plot_timer_frequency(self):
        return self.TIMER_FREQUENCY

    def get_simple_plot_layout(self):
        return self.layout

    def get_current_position_value(self):
        return self.current_position_value

    def get_simple_plot_widget(self):
        return self.simple_plot_widget

if __name__ == '__main__':
    app = QtGui.QApplication([])
    mw = QtGui.QMainWindow()
    mw.setWindowTitle('Plot')

    simple_plot_widget = SimplePlot()

    cw = QtGui.QWidget()
    ml = QtGui.QGridLayout()
    cw.setLayout(ml)
    mw.setCentralWidget(cw)

    ml.addLayout(simple_plot_widget.get_simple_plot_layout(),0,0)
    mw.show()

    # Start Qt event loop unless running in interactive mode or using pyside
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

【问题讨论】:

【参考方案1】:

这可能是因为你的情节不断地重新缩放,LabelItem 的大小并没有随之改变,而且它似乎位于 x 轴的正侧,所以你无法可视化文本.

Pyqtgraph 建议 here 使用 TextItem 而不是 LabelItem,在缩放视图中显示文本。

我尝试使用TextItem,它工作正常,但它的默认位置不好,可能是因为你的情节在负象限。只需像这样使用setPos() 方法:

# Update label value
self.label_value.setPos(QtCore.QPointF(-9, 0.6*min(self.data)))
self.label_value.setText(str(self.dataPoint))

它应该做你想做的。

【讨论】:

以上是关于在 PlotWidget 中添加自定义标签的主要内容,如果未能解决你的问题,请参考以下文章

Qt自定义标签按钮

Django的自定义标签

360浏览器自定义设置内核模式说明

solidworks自定义属性和零件属性的区别

如何创建自定义标签栏...在标签栏中添加自定义图像(无需 xib 更改)

如何用jquery获取页面中的自定义标签