Hi, does anyone have an example implementation? Thanks. понедельник, 29 апреля 2019 г. в 08:30:00 UTC+7, Patrick:
> Hi, > > Yeah, the dataBounds() functionality doesn't seem to be "official", in > that the ViewBox code > <http://www.pyqtgraph.org/documentation/_modules/pyqtgraph/graphicsItems/ViewBox/ViewBox.html#ViewBox.childrenBounds> > > just checks for the existence of the method and uses it if available, else > defaults to what is provided by item's BoundingRect(). > > Patrick > > > On Sunday, 28 April 2019 16:58:09 UTC+9:30, Anthony S wrote: > >> 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/a441c915-7011-4f63-89d9-a94bf71108f4n%40googlegroups.com.
