Change colour of plot depending on the value

178 views
Skip to first unread message

Mike Oliver

unread,
Jan 25, 2018, 2:29:28 AM1/25/18
to pyqtgraph
Is there a way to easily change the colour of a plot line based on some criteria.  Im trying to achieve something like the image below without drawing a separate plot for each segment
Thanks!


Mike Oliver

unread,
Jan 31, 2018, 3:37:40 AM1/31/18
to pyqtgraph
So I managed to get this working but its incredibly slow on large data sets.  Is there a better way to do this?

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

win = pg.GraphicsWindow()
p1 = win.addPlot()
values = [10,50,8,64,45,9,6,12,6,43,3,7,33,67,82,42,12,7,40,8]

for i in range(len(values)-1):
    if values[i]>values[i+1]:
        p1.plot([i,i+1],values[i:i+2], pen=(255,0,0))
    else:
        p1.plot([i,i+1],values[i:i+2], pen=(0,255,0))

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()



Carlos Pascual

unread,
Jan 31, 2018, 4:40:25 AM1/31/18
to pyqt...@googlegroups.com, Mike Oliver
Hi Mike,

With this approach you are creating as many curve objects as segments, and on
top of that you are doing a for loop on each point of your data so it is
reasonable to expect it to be very inefficient.

Have you considered deriving from pyqtgraph.PlotDataItem and reimplement its
paint() method to pass a different QPainter depending on the segment being
painted?

Not sure if that would be the best (or simpler) approach, but it is what I
would first try...

Cheers,
Carlos
--
+----------------------------------------------------+
Carlos Pascual Izarra
Scientific Software Coordinator
Computing Division
ALBA Synchrotron [http://www.albasynchrotron.es]
Carrer de la Llum 2-26
E-08290 Cerdanyola del Valles (Barcelona), Spain
E-mail: cpas...@cells.es
Phone: +34 93 592 4428
+----------------------------------------------------+

Mike Oliver

unread,
Feb 2, 2018, 2:10:37 AM2/2/18
to pyqtgraph
Thanks Carlos, Ill look into that.

Jannis Mainczyk

unread,
Feb 5, 2018, 6:31:27 AM2/5/18
to pyqtgraph
Hi Mike,

I would be interested in your solution. I have a similar problem, where I want to hide certain values without creating new PlotItems each time. Painting them black would also do the job :-)

I will also have a go at it the next time I touch my plotting module.

Cheers,
Jannis

Mike Oliver

unread,
Feb 6, 2018, 1:45:42 AM2/6/18
to pyqtgraph
I managed to find a solution using QPainter.  I just re-purposed the candlestick example.  I cant believe I didn't think of that before.

import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import numpy as np

class LinePlot(pg.GraphicsObject):
   def __init__(self, data):
       pg.GraphicsObject.__init__(self)
       pg.setConfigOptions(antialias=True)

       self.data = data
       self.width = 2
       self.pos = (55,108,91,255)
       self.neg = (131,54,70,255)
       self.generatePicture()

    def generatePicture(self):
       self.picture = QtGui.QPicture()
       p = QtGui.QPainter(self.picture)

        for i in range(len(self.data)-1):
           if data[i] > data[i+1] :
               p.setPen(pg.mkPen(self.neg, width = self.width))
           else:
               p.setPen(pg.mkPen(self.pos,width = self.width))
           p.drawLine(QtCore.QPointF(i, self.data[i]), QtCore.QPointF(i+1, self.data[i+1]))

    def paint(self, p, *args):
       p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
       return QtCore.QRectF(self.picture.boundingRect())


if __name__ == '__main__':
   import sys

   data = np.random.normal(size=1000)
   item = LinePlot(data)
   p1 = pg.plot()
   p1.addItem(item)

Mike Oliver

unread,
Feb 6, 2018, 1:47:22 AM2/6/18
to pyqtgraph
Also thanks to Carlos for the suggestion.  His post was what made me look at the candlestick example again.
Reply all
Reply to author
Forward
0 new messages