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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to