Я использую 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
со свечой, она не может показать строку на графике. Только можно показать строку без подсвечника.
Любая идея?