I think that you are correct thanks for the pointers. I found this after a bit of digging: https://github.com/pyqtgraph/pyqtgraph/issues/60
The databounds method doesnt seem to be documented for more complex objects, I will need to research it a bit more. On Fri, Apr 26, 2019, 11:25 PM Patrick <[email protected]> wrote: > Hi, > > I don't have experience writing custom GraphicsObjects, but I think the > ViewBox autoscale is doing what it is told to do - it's the way your > CandlestickItem is being drawn and/or the way it reports its size to the > containing ViewBox when it does its auto ranging. > > At the moment, you construct a QPicture on initialisation containing the > drawn candlesticks, and then just draw the picture on paint(). The > boundingRect is correct, it is the region that the picture will be painted > to. But I think you also need to implement a dataBounds() method ( > http://www.pyqtgraph.org/documentation/graphicsItems/plotdataitem.html#pyqtgraph.PlotDataItem.dataBounds) > to report to the ViewBox the range currently in view. This will need to do > something like find the intersection of the current self.viewRect() and the > data and return the proper range. See maybe the implementations in one of > the core GraphicsObjects like PlotCurveItem ( > http://www.pyqtgraph.org/documentation/_modules/pyqtgraph/graphicsItems/PlotCurveItem.html > <http://www.pyqtgraph.org/documentation/_modules/pyqtgraph/graphicsItems/PlotCurveItem.html#PlotCurveItem> > ). > > Also as an aside, you might be able to stop manual plot scaling and > enforce autorange (when you get it working!) with > http://www.pyqtgraph.org/documentation/graphicsItems/viewbox.html#pyqtgraph.ViewBox.setMouseEnabled > methods. > > Hope that helps, > Patrick > > On Saturday, 27 April 2019 02:50:47 UTC+9:30, [email protected] wrote: >> >> It seems like adding in any custom GraphicItems to a plot breaks >> autoranging in PyQTgraph, at least it seems to me. >> >> I added an example below, even when the candlestick item is off to the >> side of the plot and is not visible autorange still acts as though it is >> onscreen. >> >> Any ideas of the path to take to get it working ? >> >> Thanks. >> >> >> >> >> >> >> >> >> >> >> >> 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_() >> >> >> >> -- > You received this message because you are subscribed to the Google Groups > "pyqtgraph" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/pyqtgraph/963edefe-f996-4de7-ab65-b857c5913817%40googlegroups.com > <https://groups.google.com/d/msgid/pyqtgraph/963edefe-f996-4de7-ab65-b857c5913817%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "pyqtgraph" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/CAP_wP_Abba4azWsDaAEJ9W%3Dd57daotgvccgtxJ4X1C1n-xuEQQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
