如何使用pyqt5使用pyqt5在烛台中设置轴间隔?

时间:2018-04-30 06:41:13

标签: python-3.x pyqt5 pyqtgraph

我正在使用pyqtgraph绘制如下的烛台:

#-------------------
# Create pyqtgraph module 
#------------------- 
def GUI_DRAW_create():
    """
    set default config
    """
    pg.setConfigOption('background', 'w')   #background: white
    pg.setConfigOption('foreground', 'k')   #font: black

class TimeAxisItem(pg.AxisItem):
    def tickStrings(self, values, scale, spacing):
        #values is not my date in timestamp 
        return [datetime.fromtimestamp(value) for value in values]

## 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('k'))
        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()
        # I try to print out t here, is my date 
    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())


class GUI_DRAW_new(QMainWindow):
    def __init__(self):
        super().__init__()

        GUI_DRAW_create()

        self.setWindowTitle("pyqtgraph example: PlotWidget")

        cw = QWidget()
        self.setCentralWidget(cw)

        main_layout = QHBoxLayout()
        cw.setLayout(main_layout)

        #variable 
        self.signalgraph = None
        self.data = []
        self.vb = None
        self.vLine = None

        # define plot windows
        self.GUI_DRAW_new_graph()
        main_layout.addWidget(self.signalgraph)

        self.signalgraph.setMouseTracking(True)
        self.signalgraph.viewport().installEventFilter(self)

        self.show()

    def eventFilter(self, source, event):
        try:
            if (event.type() == QtCore.QEvent.MouseMove and
                source is self.signalgraph.viewport()):
                pos = event.pos()
                print('mouse move: (%d, %d)' % (pos.x(), pos.y()))
                if self.signalgraph.sceneBoundingRect().contains(pos):
                    mousePoint = self.vb.mapSceneToView(pos)
                    index = int(mousePoint.x())
                    int(index)
                    #if index > 0 and index < len(self.data):
                        #print(self.xdict[index])

                    #    self.label.setHtml("<p style='color:black'>日期:{0}</p>".format(self.data[index]))
                    #    self.label.setPos(mousePoint.x(),mousePoint.y())
                    self.vLine.setPos(mousePoint.x())

            return QtGui.QWidget.eventFilter(self, source, event)
        except Exception as e:
            traceback.print_exc()
            err = sys.exc_info()[1]
            PRINT_DEBUG(0,str(err))

    def GUI_DRAW_new_graph(self):
        try:
            self.signalgraph = pg.PlotWidget(name="Signalgraph", axisItems={'bottom': TimeAxisItem(orientation='bottom')})

            # sample data
            self.data = [  ## fields are (time, open, close, min, max).
                (1514995200.0, 102.610001, 105.349998, 102, 105.370003),
                (1515081600.0, 105.75, 102.709999, 102.410004, 105.849998),
                (1515168000.0, 100.559998, 102.370003, 99.870003, 100.699997),
                (1515254400.0, 98.68, 96.449997, 96.43, 100.129997),
                (1515340800.0, 98.550003, 96.959999, 96.760002, 99.110001),

                (1515427200.0, 102.610001, 105.349998, 102, 105.370003),
                (1515513600.0, 105.75, 102.709999, 102.410004, 105.849998),
                (1515600000.0, 100.559998, 102.370003, 99.870003, 100.699997),
                (1515686400.0, 98.68, 96.449997, 96.43, 100.129997),
                (1515772800.0, 98.550003, 96.959999, 96.760002, 99.110001),
            ]

            #if comment this 2 code, can see the string
            item = CandlestickItem(self.data)
            self.signalgraph.addItem(item)

            #trick
            s_day = datetime.fromtimestamp(self.data[0][0]).strftime("%Y-%m-%d")
            e_day = datetime.fromtimestamp(self.data[len(self.data) - 1][0]).strftime("%Y-%m-%d")
            tr=np.arange(s_day, e_day, dtype='datetime64') # tick labels one day 

            tday0=(tr-tr[0])/(tr[-1]-tr[0])  #Map time to 0.0-1.0 day 2 1.0-2.0 ...
            tday1=tday0+1

            tnorm=np.concatenate([tday0,tday1])
            tr[-1]=tr[0]  # End day=start next day

            ttick=list()    
            for i,t in enumerate(np.concatenate([tr,tr])):
                tstr=np.datetime64(t).astype(datetime)
                ttick.append(  (tnorm[i],  tstr.strftime("%Y-%m-%d")))  

            ax=self.signalgraph.getAxis('bottom')    #This is the trick  
            ax.setTicks([ttick])
            #cross hair in signalgraph
            self.vLine = pg.InfiniteLine(angle=90, movable=False)
            self.signalgraph.addItem(self.vLine, ignoreBounds=True)
            self.vb = self.signalgraph.plotItem.vb

        except Exception as e:
            traceback.print_exc()
            err = sys.exc_info()[1]
            print(0,str(err))


# Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == "__main__":
    app = QtGui.QApplication([])
    gui = GUI_DRAW_new()
    app.exec_()

结果是:

candlestick_graph_center

我想使用日期设置x轴间隔:[2018-01-04,2018-01-05,2018-01-06,....]。 感谢您的帮助,非常感谢

更新

由于TextItem,我弄清楚为什么所有数据都会挤在一起。 所以,我重写了代码。

我尝试在tickStrings中使用AxisItem将值转换为字符串,当我打印values中的tickStrings时,它不是我的数据值(日期为时间戳)。为什么价值观不同?非常感谢

更新

如果我使用蜡烛棒setTicks,则无法在图表中显示字符串。只能显示没有蜡烛棒的字符串。 任何的想法?

1 个答案:

答案 0 :(得分:0)

您必须使用strftime()转换为具有相应格式的字符串:

from datetime import datetime

class TimeAxisItem(pg.AxisItem):
    def tickStrings(self, values, scale, spacing):
        #values is not my date in timestamp 
        return [datetime.fromtimestamp(value).strftime("%Y-%m-%d") for value in values]

或者:

from datetime import date

class TimeAxisItem(pg.AxisItem):
    def tickStrings(self, values, scale, spacing):
        #values is not my date in timestamp 
        return [date.fromtimestamp(value) for value in values]

或者:

from datetime import datetime

class TimeAxisItem(pg.AxisItem):
    def tickStrings(self, values, scale, spacing):
        #values is not my date in timestamp 
        return [datetime.fromtimestamp(value).date() for value in values]

enter image description here