在自定义pyqtgraph绘图小部件中实现十字线,如pyqtgraph股票示例中所示

2024-09-24 22:21:09 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的(widgetized)pyqtgraph图中,我希望具有交叉线功能,如模块示例中所示。 详细地说,我附加了3个Python文件:

  1. crosshair.py:这是实现我希望在我的小部件中具有的十字线的模块的库存示例

  2. plotdashboard.py:这是我制作成一个小部件的PyQTraph,这样我就可以从另一个Python程序(下面是myplots.py)调用它,但我不知道如何实现十字线

  3. myplots.py:只需运行此命令,它将创建PlotDashboard的实例(已定义的PlotDashboard.py)

因此,我想在PlotDashboard.py中的类PlotDashboard中实现十字线,如crosshair.py示例所示

crosshair.py的文件代码

import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.Point import Point

#generate layout
app = QtGui.QApplication([])
win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('pyqtgraph example: crosshair')
label = pg.LabelItem(justify='right')
win.addItem(label)
p1 = win.addPlot(row=1, col=0)

region = pg.LinearRegionItem()
region.setZValue(10)

p1.setAutoVisible(y=True)

#create numpy arrays
#make the numbers large to show that the xrange shows data from 10000 to all the way 0
data1 = 10000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
data2 = 15000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)

def update():
    region.setZValue(10)
    minX, maxX = region.getRegion()
    p1.setXRange(minX, maxX, padding=0)

region.sigRegionChanged.connect(update)

def updateRegion(window, viewRange):
    rgn = viewRange[0]
    region.setRegion(rgn)

p1.sigRangeChanged.connect(updateRegion)

region.setRegion([1000, 2000])

#cross hair
vLine = pg.InfiniteLine(angle=90, movable=False)
hLine = pg.InfiniteLine(angle=0, movable=False)
p1.addItem(vLine, ignoreBounds=True)
p1.addItem(hLine, ignoreBounds=True)

vb = p1.vb

def mouseMoved(evt):
    pos = evt[0]  ## using signal proxy turns original arguments into a tuple
    if p1.sceneBoundingRect().contains(pos):
        mousePoint = vb.mapSceneToView(pos)
        index = int(mousePoint.x())
        if index > 0 and index < len(data1):
            label.setText("<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y1=%0.1f</span>,   <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index], data2[index]))
        vLine.setPos(mousePoint.x())
        hLine.setPos(mousePoint.y())

proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)

p1.plot(data1, pen="r")
p1.plot(data2, pen="g")

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

crosshair.py的输出

十字线输出图像: crosshair output image

plotdashboard.py的文件代码

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import numpy as np
import pyqtgraph as pg

class PlotDashboard(QWidget):
    def __init__(self, title, parent=None):
       '''Constructor
        '''
        QWidget.__init__(self, parent)
        self.layout = QVBoxLayout(self)
        self.setLayout(self.layout)
                                       
        # Create a plot with a date-time axis
        self.p1 = pg.PlotWidget(name='Plot1', background=QColor(5, 27, 105, 255), axisItems = {'bottom': pg.DateAxisItem()})  ## giving the plots names allows us to link their axes together
        self.p1.setTitle("<strong>" + title + "</strong>")
        self.p1.getAxis("left").setPen(pg.mkPen(color='w', width=2))
        self.p1.getAxis("bottom").setPen(pg.mkPen(color='w', width=2))        
    
        self.p1.showGrid(x=True, y=True, alpha = 0.3)
        self.p1.setLabel('left', 'Value')
        self.p1.setLabel('bottom', 'Time')        
        self.p1.addLegend()     
                                      
        # Add layout
        self.layout.addWidget(self.p1)        
    
        self.btnClear = QPushButton(text = 'Clear All')        
        self.btnClear.setIcon(QIcon(QPixmap('/usr/local/lib/python2.7/dist-packages/taurus/qt/qtgui/icon/Tango/scalable/actions/editclear.svg')))
        self.btnClear.clicked.connect(self.clearAll)        
        self.layout.addWidget(self.btnClear)
    
        # Data holders for cross hair- Plot max 5 data sets
        self.data1 = [[], []] # x and y in separate lists
        self.data2 = [[], []]
        self.data3 = [[], []]
        self.data4 = [[], []]
        self.data5 = [[], []]
    
        self.curvesData = [self.data1, self.data2, self.data3, self.data4, self.data5]                
        self.numCurves = 0 # number of curves plotted, runs from 0 to 3                                                             
                                                                 
    def plotCurve(self, data, curve_name):
        if len(data[0]) == 0 or len(data[1]) == 0: return
        if len(data[0]) != len(data[1]): return
        if self.numCurves > 4: return # support plotting max 5 curves, need to clear all first
       
        self.curvesData[self.numCurves] = data
        self.p1.addLegend()

        if self.numCurves == 0:
            _pen=(255,0,255)
            self.data1 = [data[0], data[1]]
        elif self.numCurves == 1:
            _pen=(0,255,0)
            self.data2 = [data[0], data[1]]         
        elif self.numCurves == 2:
            _pen=(255,100,0)
            self.data3 = [data[0], data[1]]
        elif self.numCurves == 3:
            _pen=(255,255,255)
            self.data4 = [data[0], data[1]]     
        else:
            _pen=(255,255,0)
            self.data5 = [data[0], data[1]]
                                
        self.p1.plot(data[0], data[1], pen=_pen, symbolBrush=_pen, symbolPen='w', symbol='o', symbolSize=14, name=curve_name)  
        self.numCurves += 1
                        
    def clearAll(self):     
        self.p1.clear()
        self.data1 = [[], []]
        self.data2 = [[], []]
        self.data3 = [[], []]
        self.data4 = [[], []]
        self.data5 = [[], []]
    
        self.curvesData = [self.data1, self.data2, self.data3, self.data4, self.data5]                 
        self.numCurves = 0

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = PlotDashboard("PLOT 1")
    gui.show()
    sys.exit(app.exec_())

plotdashboard.py的输出

plotdashboard输出图像:
plotdashboard output image

myplots.py的文件代码

from plotdashboard import PlotDashboard
import sys
import PyQt4.QtGui as QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *

import pytz
from datetime import datetime

def to_timestamp(a_date):
    if a_date.tzinfo:
        epoch = datetime(1970, 1, 1, tzinfo=pytz.UTC)
        diff = a_date.astimezone(pytz.UTC) - epoch
    else:
        epoch = datetime(1970, 1, 1)
        diff = a_date - epoch
    return int(diff.total_seconds())

if __name__ == "__main__":
    app = QApplication(sys.argv)

    plot = PlotDashboard("PLOT 1")        
    plot.show()

    interval = 7200 # 2 hours in seconds
    dt9 = to_timestamp(datetime.now())
    dt8 = dt9 - interval
    dt7 = dt8 - interval
    dt6 = dt7 - interval
    dt5 = dt6 - interval
    dt4 = dt5 - interval
    dt3 = dt4 - interval
    dt2 = dt3 - interval
    dt1 = dt2 - interval

    # curve 1
    x1 = [dt1, dt2, dt3, dt4, dt5]
    y1 = [10, 20, 30, 40, 50]    
    data1 = [x1, y1]    
    plot.plotCurve(data1, 'curve 1')

    # curve 2
    x2 = [dt2, dt3, dt4, dt5, dt6]
    y2 = [30, 40, 50, 60, 70]    
    data2 = [x2, y2]    
    plot.plotCurve(data2, 'curve 2')

    # curve 3
    x3 = [dt3, dt4, dt5, dt6, dt7]
    y3 = [50, 60, 70, 80, 90]    
    data3 = [x3, y3]    
    plot.plotCurve(data3, 'curve 3')    

    # curve 4
    x4 = [dt4, dt5, dt6, dt7, dt8]
    y4 = [70, 80, 90, 100, 110]    
    data4 = [x4, y4]    
    plot.plotCurve(data4, 'curve 4')

    # curve 5
    x5 = [dt5, dt6, dt7, dt8, dt9]
    y5 = [90, 100, 110, 120, 130]    
    data5 = [x5, y5]        
    plot.plotCurve(data5, 'curve 5')         
    
    sys.exit(app.exec_())

myplots.py的输出

myplots输出图像:
myplots output image


Tags: frompyimportselfdataifplotpg