我想以最快的方式刷新蜡烛图。 但是根据修改后的样本,即使我只添加一个新栏,我也必须每次绘制整个图表。 原因是当我再次调用对象以绘制其他数据时,QPainter对象被清除。 它可能很慢。从字面上看,我只想"添加"一个条形数据。
所以有人可以教我如何重新开始绘画或给我好点子吗?
"""
Demonstrate creation of a custom graphic (a candlestick plot)
"""
import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import random
## Create a subclass of GraphicsObject.
## The only required methods are paint() and boundingRect()
## (see QGraphicsItem documentation)
class CandlestickItem(pg.GraphicsObject):
def __init__(self):
pg.GraphicsObject.__init__(self)
self.flagHasData = False
def set_data(self, data):
self.data = data ## data must have fields: time, open, close, min, max
self.flagHasData = True
self.generatePicture()
self.informViewBoundsChanged()
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):
if self.flagHasData:
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())
app = QtGui.QApplication([])
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],
]
item = CandlestickItem()
item.set_data(data)
plt = pg.plot()
plt.addItem(item)
plt.setWindowTitle('pyqtgraph example: customGraphicsItem')
def update():
global item, data
data_len = len(data)
rand = random.randint(0, len(data)-1)
new_bar = data[rand][:]
new_bar[0] = data_len
data.append(new_bar)
item.set_data(data)
app.processEvents() ## force complete redraw for every plot
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(100)
## 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_()
答案 0 :(得分:4)
以下是几个选项:
使您的自定义项目只绘制一个条形,只需为每个新数据点添加一个新项目。这样可以避免重新生成整个图片,但是当您显示许多项目时,可能会使用交互式缩放/平移来降低性能。
使用混合方法向CandleStickItem添加新柱形,直到达到某个最大大小,然后启动一个新的CandleStickItem(但也保留旧的烛台)。这样,每个新栏只会在generatePicture()中产生少量的工作量,但是你将paint()的调用总数保持在较小的位置。