import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
## Create a subclass of GraphicsObject.
## The only required methods are paint() and boundingRect()
## (see QGraphicsItem documentation)
class CandlestickItem(pg.GraphicsObject):
def __init__(self, data):
pg.GraphicsObject.__init__(self)
self.data = data ## data must have fields: time, open, close, min, max
self.generatePicture()
def generatePicture(self):
## pre-computing a QPicture object allows paint() to run much more quickly,
## rather than re-drawing the shapes every time.
self.picture = QtGui.QPicture()
p = QtGui.QPainter(self.picture)
p.setPen(pg.mkPen('w'))
w = (self.data[1][0] - self.data[0][0]) / 3.
for (t, open, close, min, max) in self.data:
p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
if open > close:
p.setBrush(pg.mkBrush('r'))
else:
p.setBrush(pg.mkBrush('g'))
p.drawRect(QtCore.QRectF(t-w, open, w*2, close-open))
p.end()
def paint(self, p, *args):
p.drawPicture(0, 0, self.picture)
def boundingRect(self):
## boundingRect _must_ indicate the entire area that will be drawn on
## or else we will get artifacts and possibly crashing.
## (in this case, QPicture does all the work of computing the bouning rect for us)
return QtCore.QRectF(self.picture.boundingRect())
# rescales Y automatically
def setYRange():
vb.enableAutoRange(x=False, y=True)
vb.setAutoVisible(x=False, y=True)
print('Why me no rescale ? =)')
data = [ ## fields are (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16),
(7., 10, 13, 5, 15),
(8., 13, 17, 9, 20),
(9., 17, 14, 11, 23),
(10., 14, 15, 5, 19),
(11., 15, 9, 8, 22),
(12., 9, 15, 8, 16),
(13., 10, 13, 5, 15),
(14., 14, 15, 5, 19),
(15., 15, 9, 8, 22),
(16., 9, 15, 8, 16),
(17., 16, 17, 15, 20),
(18., 17, 21, 20, 23),
(19., 21, 30, 29, 24),
(20., 30, 39, 28, 32),
(21., 39, 37, 35, 40)
]
plt = pg.plot()
item = CandlestickItem(data)
plt.addItem(item)
plt.setWindowTitle('Scaletest')
# normal lines
import numpy
x_data = numpy.linspace(22, 122, num=100)
y_data = (10*numpy.random.rand(100,1)+30).flatten()
#y_data[5000:] = numpy.sin(x_data[5000:])
lineitem = pg.PlotDataItem(x_data, y_data)
plt.addItem(lineitem)
# autoscale aspects
vb = plt.getViewBox()
vb.setAspectLocked(lock=False)
vb.setAutoVisible(y=1.0)
vb.enableAutoRange(axis='y', enable=True)
# force it to update at rescale
vb.sigXRangeChanged.connect(setYRange)
## 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_()