我正在使用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
,则无法在图表中显示字符串。只能显示没有蜡烛棒的字符串。
任何的想法?
答案 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]