画半无限线?

2024-09-26 22:54:04 发布

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

我使用pyqtgraph进行数据采集,并且必须在图形视图中表示一些阈值。例如代表高电压限制等。 我使用了pyqtgraph中的InfiniteLine类,但是现在,我必须考虑在获取过程中阈值可能发生的一些变化。它看起来像是两条无限线之间的一个台阶(请参阅附件中的示例)。在

example

为此,我不得不画一条半无限长的线。你知道一个简单的方法吗?在

我考虑过使用一些受viewBox最小值和最大值限制的plotCurveItem:

thresholdValue = 60V # just an example
range = self.viewBox.viewRange()
xRange = range[0]   # we only want ViewBox horizontal limits
minView = xRange[0]
maxView = xRange[1]
myPlotCurveItem = pyqtgraph.PlotCurveItem([minView, maxView],[thresholdValue, thresholdValue])

如果阈值发生变化:

^{pr2}$

plotCurveItem的x数据将变为:

[minView, changingTime]    #with changinTime : the moment we change the threshold

我们会添加一个新的曲线图:

myNewPlotCurveItem = pyqtgraph.plotCurveItem([changingTime, maxView],[newThresholdValue, newThresholdValue])

这个解决方案看起来不错还是有什么问题?在


Tags: the数据examplerange阈值wepyqtgraphxrange
2条回答

谢谢你非常完整的回答! 你的代码运行得很好。 为了设置多个阈值转换,我对你的类InfiniteLineWithBreak做了一些修改。 我只修改了init和paint方法:

def __init__(self, listOfcouplesOfThresholdAndItsDate, pen=None):
    pg.GraphicsObject.__init__(self)

    self.listOfcouplesOfThresholdAndItsDate=listOfcouplesOfThresholdAndItsDate
    self.maxRange = [None, None]
    self.moving = False
    self.movable = False
    self.mouseHovering = False

    pen = (200, 200, 100)
    self.setPen(pen)
    self.setHoverPen(color=(255,0,0), width=self.pen.width())
    self.currentPen = self.pen




 def paint(self, p, *args):
    br = self.boundingRect()
    p.setPen(self.currentPen)
    if len(self.listOfcouplesOfThresholdAndItsDate)==0:
        pass
    elif len(self.listOfcouplesOfThresholdAndItsDate)==1:
        threshold = self.listOfcouplesOfThresholdAndItsDate[0][1]
        date = self.listOfcouplesOfThresholdAndItsDate[0][0]
        p.drawLine(pg.Point(date, threshold), pg.Point(br.right(), threshold))

    else:

        threshold = self.listOfcouplesOfThresholdAndItsDate[0][1]
        date = self.listOfcouplesOfThresholdAndItsDate[0][0]
        i=0
        for i in range(0, len(self.listOfcouplesOfThresholdAndItsDate)-2):
            threshold = self.listOfcouplesOfThresholdAndItsDate[i][1]
            date = self.listOfcouplesOfThresholdAndItsDate[i][0]
            nexteDate = self.listOfcouplesOfThresholdAndItsDate[i+1][0]
            nextThreshold = self.listOfcouplesOfThresholdAndItsDate[i+1][1]
            p.drawLine(pg.Point(date, threshold), pg.Point(nexteDate, threshold))
            p.drawLine(pg.Point(nexteDate, threshold), pg.Point(nexteDate, nextThreshold))


        threshold = self.listOfcouplesOfThresholdAndItsDate[-2][1]
        date = self.listOfcouplesOfThresholdAndItsDate[-2][0]
        nexteDate = self.listOfcouplesOfThresholdAndItsDate[-1][0]
        nextThreshold = self.listOfcouplesOfThresholdAndItsDate[-1][1]
        p.drawLine(pg.Point(date, threshold), pg.Point(nexteDate, threshold))
        p.drawLine(pg.Point(nexteDate, threshold), pg.Point(nexteDate, nextThreshold))

        p.drawLine(pg.Point(nexteDate, nextThreshold), pg.Point(br.right(), nextThreshold))

此外,我还添加了一个方法,将一个新的阈值转换点附加到HersHoldAndItsDate的耦合列表中:

^{pr2}$

下面是它的一个示例: example of multiple thresholds

你觉得代码没问题吧? 谢谢你

您的方法看起来不错,主要是pyqtgraph.InfiniteLine正在做的事情。我检查了the source of InfiniteLine并提取了那些绝对必要的部分,添加了变化点和两个层次的信息,然后画了三条线(左边界到左水平的变化点,在右水平上改变点到右边界,两者的连接)。在

以下是完整代码:

from pyqtgraph.Qt import QtGui
import numpy as np
import pyqtgraph as pg

class InfiniteLineWithBreak(pg.GraphicsObject):

    def __init__(self, changeX, levelsY, pen=None):
        pg.GraphicsObject.__init__(self)

        self.changeX = changeX
        self.levelsY = levelsY

        self.maxRange = [None, None]
        self.moving = False
        self.movable = False
        self.mouseHovering = False

        pen = (200, 200, 100)
        self.setPen(pen)
        self.setHoverPen(color=(255,0,0), width=self.pen.width())
        self.currentPen = self.pen


    def setBounds(self, bounds):
        self.maxRange = bounds
        self.setValue(self.value())

    def setPen(self, *args, **kwargs):
        self.pen = pg.fn.mkPen(*args, **kwargs)
        if not self.mouseHovering:
            self.currentPen = self.pen
            self.update()

    def setHoverPen(self, *args, **kwargs):
        self.hoverPen = pg.fn.mkPen(*args, **kwargs)
        if self.mouseHovering:
            self.currentPen = self.hoverPen
            self.update()

    def boundingRect(self):
        br = self.viewRect()
        return br.normalized()

    def paint(self, p, *args):
        br = self.boundingRect()
        p.setPen(self.currentPen)
        # three lines (left border to change point, change point vertical, change point to right)
        p.drawLine(pg.Point(br.left(), self.levelsY[0]), pg.Point(self.changeX, self.levelsY[0]))
        p.drawLine(pg.Point(self.changeX, self.levelsY[0]), pg.Point(self.changeX, self.levelsY[1]))
        p.drawLine(pg.Point(self.changeX, self.levelsY[1]), pg.Point(br.right(), self.levelsY[1]))

    def dataBounds(self, axis, frac=1.0, orthoRange=None):
        if axis == 0:
            return None   ## x axis should never be auto-scaled
        else:
            return (0,0)

    def setMouseHover(self, hover):
        pass

app = QtGui.QApplication([])
w = pg.GraphicsWindow()
w.resize(1000, 600)
v = w.addPlot(y=np.random.normal(size=100))
v.addItem(InfiniteLineWithBreak(changeX=50, levelsY=(-1, 1)))
app.exec_()

它看起来像:

enter image description here

可以添加的是鼠标悬停和更改值的反应(更改点和级别),甚至旋转90度。InfiniteLine就是一个很好的例子。在

相关问题 更多 >

    热门问题