¿Cómo usar un Qthread para actualizar una figura de Matplotlib con PyQt?

Realmente me está costando entender cómo usar Threads en PyQt. Hice un ejemplo simple de lo que me gustaría hacer en mi interfaz de usuario. En el código que puede ver a continuación, quiero que el usuario ingrese un ticker de acciones (puede ingresar "bby", "goog" o "v", por ejemplo) y graficar el valor de las acciones durante un período determinado. La cosa está en una interfaz de usuario más compleja o durante un largo período de tiempo, la interfaz de usuario se congela mientras la trama se actualiza. Así que hice una clase de "Plotter" que actualiza la trama cuando recibe una cierta señal (anular Qthread.run aparentemente no era la forma correctalo estás haciendo mal) Me gustaría hacer que este "Plotter" se ejecute en otro hilo que no sea el principal.

Tan pronto como descomento las líneas de hilo, el programa deja de funcionar. He tratado de mover el lanzamiento del nuevo hilo y también el "conectar", pero nada funciona. Creo que no entiendo bien cómo funciona Qthread incluso después de leer eldocumentación y mirando los ejemplos en el sitio web de Qt.

Si alguno sabe cómo hacer esto, ¡sería de gran ayuda! (Estoy trabajando con Python 3.5 y PyQt5)

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from matplotlib.axes._subplots import Axes
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import sys
from datetime import datetime, timedelta
import time
import quandl


class MyMplCanvas(FigureCanvas):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    send_fig = pyqtSignal(Axes, str, name="send_fig")

    def __init__(self, parent=None):
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)

        # We want the axes cleared every time plot() is called
        self.axes.hold(False)

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def update_plot(self, axes):
        self.axes = axes
        self.draw()

class MainWindow(QMainWindow):
    send_fig = pyqtSignal(Axes, str, name="send_fig")

    def __init__(self):
        super().__init__()

        self.main_widget = QWidget(self)
        self.myplot = MyMplCanvas(self.main_widget)
        self.editor = QLineEdit()
        self.display = QLabel("Vide")

        self.layout = QGridLayout(self.main_widget)
        self.layout.addWidget(self.editor)
        self.layout.addWidget(self.display)
        self.layout.addWidget(self.myplot)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.move(500, 500)
        self.show()

        self.editor.returnPressed.connect(self.updatePlot)

        self.plotter = Plotter()
        self.send_fig.connect(self.plotter.replot)

        self.plotter.return_fig.connect(self.myplot.update_plot)


    def updatePlot(self):
        ticker = self.editor.text()
        self.editor.clear()
        self.display.setText(ticker)

        # thread = QThread()
        # self.plotter.moveToThread(thread)

        self.send_fig.emit(self.myplot.axes, ticker)

        # thread.start()


class Plotter(QObject):
    return_fig = pyqtSignal(Axes)

    @pyqtSlot(Axes, str)
    def replot(self, axes, ticker):  # A slot takes no params
        print(ticker)
        d = datetime.today() - timedelta(weeks=52)  # data from 1week ago
        data = quandl.get("YAHOO/"+ticker+".6", start_date=d.strftime("%d-%m-%Y"), end_date=time.strftime("%d-%m-%Y"))
        axes.plot(data)
        self.return_fig.emit(axes)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())

Respuestas a la pregunta(1)

Su respuesta a la pregunta