1# -*- coding: utf-8 -*-
2"""
3This example demonstrates the creation of a plot with
4DateAxisItem and a customized ViewBox.
5"""
6
7
8import initExample ## Add path to library (just for examples; you do not need this)
9
10import pyqtgraph as pg
11from pyqtgraph.Qt import QtCore, QtGui
12import numpy as np
13import time
14
15class CustomViewBox(pg.ViewBox):
16    def __init__(self, *args, **kwds):
17        kwds['enableMenu'] = False
18        pg.ViewBox.__init__(self, *args, **kwds)
19        self.setMouseMode(self.RectMode)
20
21    ## reimplement right-click to zoom out
22    def mouseClickEvent(self, ev):
23        if ev.button() == QtCore.Qt.MouseButton.RightButton:
24            self.autoRange()
25
26    ## reimplement mouseDragEvent to disable continuous axis zoom
27    def mouseDragEvent(self, ev, axis=None):
28        if axis is not None and ev.button() == QtCore.Qt.MouseButton.RightButton:
29            ev.ignore()
30        else:
31            pg.ViewBox.mouseDragEvent(self, ev, axis=axis)
32
33class CustomTickSliderItem(pg.TickSliderItem):
34    def __init__(self, *args, **kwds):
35        pg.TickSliderItem.__init__(self, *args, **kwds)
36
37        self.all_ticks = {}
38        self._range = [0,1]
39
40    def setTicks(self, ticks):
41        for tick, pos in self.listTicks():
42            self.removeTick(tick)
43
44        for pos in ticks:
45            tickItem = self.addTick(pos, movable=False, color="#333333")
46            self.all_ticks[pos] = tickItem
47
48        self.updateRange(None, self._range)
49
50    def updateRange(self, vb, viewRange):
51        origin = self.tickSize/2.
52        length = self.length
53
54        lengthIncludingPadding = length + self.tickSize + 2
55
56        self._range = viewRange
57
58        for pos in self.all_ticks:
59            tickValueIncludingPadding = (pos - viewRange[0]) / (viewRange[1] - viewRange[0])
60            tickValue = (tickValueIncludingPadding*lengthIncludingPadding - origin) / length
61
62            # Convert from np.bool_ to bool for setVisible
63            visible = bool(tickValue >= 0 and tickValue <= 1)
64
65            tick = self.all_ticks[pos]
66            tick.setVisible(visible)
67
68            if visible:
69                self.setTickValue(tick, tickValue)
70
71app = pg.mkQApp()
72
73axis = pg.DateAxisItem(orientation='bottom')
74vb = CustomViewBox()
75
76pw = pg.PlotWidget(viewBox=vb, axisItems={'bottom': axis}, enableMenu=False, title="PlotItem with DateAxisItem, custom ViewBox and markers on x axis<br>Menu disabled, mouse behavior changed: left-drag to zoom, right-click to reset zoom")
77
78dates = np.arange(8) * (3600*24*356)
79pw.plot(x=dates, y=[1,6,2,4,3,5,6,8], symbol='o')
80
81# Using allowAdd and allowRemove to limit user interaction
82tickViewer = CustomTickSliderItem(allowAdd=False, allowRemove=False)
83vb.sigXRangeChanged.connect(tickViewer.updateRange)
84pw.plotItem.layout.addItem(tickViewer, 4, 1)
85
86tickViewer.setTicks( [dates[0], dates[2], dates[-1]] )
87
88pw.show()
89pw.setWindowTitle('pyqtgraph example: customPlot')
90
91r = pg.PolyLineROI([(0,0), (10, 10)])
92pw.addItem(r)
93
94if __name__ == '__main__':
95    pg.exec()
96