Goal:
I want to embed a Matplotlib plot in a pyQt4 GUI window. The plot has to update in time.
Problem:
The window freezes until the plotting has finished. I want the plot to be updated in real time.
Context:
We have numerical algorithm that is working on some data and I want the plot to show how the dataset is being affected by algorithm. The algorithm finishes an iteration ever ~0.5 seconds - the plot must be updated every iteration.
Test Code:
The algorithm is replaced by test(), which plots a random point 100 times. The code below illustrates the problems:
import sys
from PlotGUI import *
import threading
from random import randint
import time
class GUIForm(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self,parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.startSim)
self.cPlot = None # custom plotter
self.instantiatePlot()
def instantiatePlot(self):
self.cPlot = CustomPlotter(self.ui.widget.canvas)
self.cPlot.prepareFigure()
def startSim(self):
self.cPlot.clear();
draw_thread = threading.Thread(target=self.cPlot.test())
draw_thread.start()
class CustomPlotter():
def __init__(self, canvas):
print 'constructor'
self.canvas = canvas
def prepareFigure(self):
ax = self.canvas.ax
ax.set_ylim([-1,101])
#ax.set_xlim([dt[0],dt[1]])
ax.set_ylim([-1, 10])
self.canvas.draw()
def clear(self):
self.canvas.ax.clear()
def test(self):
canvas = self.canvas
ax = canvas.ax
for x in range(0,100):
y = randint(0,9)
ax.plot(x, y, 'ro')
print x
canvas.draw()
time.sleep(1)
#canvas.show()
#canvas.update()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = GUIForm()
myapp.show()
sys.exit(app.exec_())
Thanks in advance. This is for some prototyping, so I'd be open to all options / alternatives that offer a quick'ish solution.
QThreadand signal emission - there are plenty of questions on SO about that)