I'm having trouble with canvas.update() not removing the previous draw_artist except only on canvas.draw(). What I'm trying to do is draw a verticle line across 30+ subplots in a timely fashion (i.e no noticeable delay between mouse and verticle line position). If I use canvas.draw() instead of canvas.update(), there is a significant delay due to the number of subplots that are being redrawn. The code I've implemented for the mouse mouse which draws the verticle line is shown below. The hovering line which spans across all subplots is initialized already when the user double click. Is there any way to remove the delay if I use canvas.draw(), or remove the previous drawn vertical line if I use canvas.update().
def onMove(self, event):
if (dblclicked):
self.hoveringLine.set_xdata(event.xdata)
self.canvas.axis1.draw_artist(self.hoveringLine)
self.canvas.update()
Edit #2: Here is the complete code, I apologize for the incomplete comments.
from PyQt4 import QtGui, QtCore
import sys
import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
class Canvas(FigureCanvasQTAgg):
def __init__(self, parent=None):
self.figure = Figure()
super(Canvas, self).__init__(self.figure)
self.ax1 = self.figure.add_subplot(1,1,1)
self.figure.subplots_adjust(left = 0.05, bottom = 0.02, right = 0.98, top = 0.99)
self.setMinimumWidth(1000)
self.ax1.plot([1,2,3])
self.draw()
def add_subplot(self, data=[]):
rows = len(self.figure.axes) + 1
for index, axes in enumerate(self.figure.axes, start=1):
axes.change_geometry(rows, 1, index)
ax = self.figure.add_subplot(rows, 1, index+1)
ax.plot(data)
ax.patch.set_facecolor('None')
self.figure.set_figheight(self.figure.get_figheight()*1.1)
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.showMaximized()
self.widget = QtGui.QWidget()
self.setCentralWidget(self.widget)
self.widget.setLayout(QtGui.QVBoxLayout())
self.widget.layout().setContentsMargins(0,0,0,0)
self.widget.layout().setSpacing(5)
self.canvas = Canvas(self)
self.scroll = QtGui.QScrollArea(self.widget)
self.scroll.setWidget(self.canvas)
self.scroll.setWidgetResizable(False)
self.numSubplots = 15
for x in range(self.numSubplots):
self.canvas.add_subplot()
self.canvas.adjustSize()
self.canvas.draw()
self.widget.layout().addWidget(self.scroll)
self.showVline = False
self.hoveringLine = None
self.canvas.mpl_connect("button_press_event", self.onClick)
self.canvas.mpl_connect("motion_notify_event", self.onMove)
def onClick(self, event):
if event.dblclick and self.showVline == False:
self.showVline = True
self.hoveringLine = self.canvas.ax1.axvline(x=event.xdata, ymin=-1.2*self.numSubplots, ymax=1.2,
lw=2, zorder=0, clip_on=False)
elif event.dblclick and self.showVline:
self.showVline = False
self.hoveringLine = None
self.canvas.ax1.axvline(x=event.xdata, ymin=-1.2*self.numSubplots, ymax=1.2,
lw=2, zorder=0, clip_on=False)
self.canvas.draw()
else:
pass
def onMove(self, event):
if (self.showVline):
self.hoveringLine.set_xdata(event.xdata)
self.canvas.ax1.draw_artist(self.hoveringLine)
self.canvas.update()
#self.canvas.draw() works as desired but there is a delay due to redrawing
#self.canvas.draw()
def main():
app = QtGui.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
GUI = Window()
GUI.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()