Могу ли я использовать axes.lines.remove (line) метода осей matplot из другого потока? - PullRequest
0 голосов
/ 15 мая 2018

Я использую matplotlib для построения графика, как показано ниже.

для добавления линий графика к рисунку. Я использую основной поток графического интерфейса пользователя (с методом pyplot.plot) и рабочий / другой поток для обновления данных оси графика, поскольку число графиков больше.Функция обновления запускается потоком, я использовал для удаления некоторых нежелательных сюжетных линий.разрешено ли удаление линий графика из рабочего / другого потока?

Как показано в коде, я удаляю строку, как показано ниже: если len (self.plot_lines)> 5: # удалить последнюю строку до полной строки = 5 self.axes_plot.lines.remove (self.plot_lines.pop ())

, пожалуйста, пройдите по приведенному ниже коду

import os
import sys
import random
import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt

from PyQt4 import QtCore, QtGui


class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        vbox = QtGui.QVBoxLayout()
        vbox.addStretch(1)
        self.setLayout(vbox)
        self.setWindowTitle('Update Plot with Qthread.....')
        self.threadpool = QtCore.QThreadPool()
        self.threadpool.setMaxThreadCount(2)
        self.timer = QtCore.QTimer()        # to update plot on some time interval
        self.timer.timeout.connect(self.timerEventOccued)
        # Add figure object using figurecanvas
        self.figure = plt.figure()
        self.canvas  = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        vbox.addWidget(self.canvas)
        vbox.addWidget(self.toolbar)
        self.canvas.draw()
        # draw plot using main thread
        self.draw_plot()


    def timerEventOccued(self):
        worker = Worker(self.updatePlot)
        self.threadpool.start(worker)  # Execute using Qthread

    def draw_plot(self):
        rect = [0.07, 0.065, 1, 1]
        self.axes_plot = self.figure.add_axes(rect, xlabel='Xaxis (deg)', ylabel='Yaxis (deg)')
        self.figure.gca().xaxis.labelpad = 0
        self.figure.gca().yaxis.labelpad = 0
        self.figure.gca().tick_params(axis='both', which='major', labelsize=7)
        self.figure.gca().tick_params(axis='both', which='minor', labelsize=12)
        self.axes_plot.margins(.20, .20)
        self.plot_lines = [ self.axes_plot.plot([],[],marker='o')[0] for i in range(0,10)]  # Create 10 plot lines 
        self.timerEventOccued()
        if not self.timer.isActive():
            self.timer.start(1500)

    def updatePlot(self):
        """This function will be run by worker thread"""
        for index,line in enumerate(self.plot_lines):
            data = index * (random.random())
            line.set_data([0,data],[0,data])

        if len(self.plot_lines) > 5: # remove last line untill total line = 5
            self.axes_plot.lines.remove(self.plot_lines.pop())    

        self.axes_plot.relim()
        self.axes_plot.autoscale_view()
        self.canvas.draw()



class Worker(QtCore.QRunnable):
    """
    Worker thread

    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
    """

    def __init__(self, fn, *args, **kwargs):
        super(Worker, self).__init__()
        # Store constructor arguments (re-used for processing)
        self.fn = fn
        self.args = args
        self.kwargs = kwargs


    @QtCore.pyqtSlot()
    def run(self):
        """
        Initialise the runner function with passed args, kwargs.
        """

        # Retrieve args/kwargs here; and fire processing using them
        try:
            self.fn(*self.args, **self.kwargs)
        except Exception as E:
            print "Exception while worker Thread Run", str(E)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

Могу ли я удалить объект аннотации и стрелки или любую линию графика из рабочего /другой поток?

Приведенный выше код является простым примером того, как добавить строку графика и обновить ее, но в моем сложном коде с той же архитектурой я использовал исключение ниже, которое вызывает дамп ядра.

Я получил журналы ниже после того, как произошел дамп ядра, и этот сценарий не является согласованным.

Исключение RuntimeError: RuntimeError ('основной поток не находится в основном цикле',) в> игнорируется Tcl_AsyncDelete: обработчик async удален не тем потоком

Пожалуйста, дайте мне знать, если я пропускаю какой-то шаг для использования matplotlib с потоками.

...