我可以从其他线程使用matplot axes方法的axes.lines.remove(line)吗?

时间:2018-05-15 13:04:42

标签: python matplotlib pyqt4 python-multithreading

我使用matplotlib绘制图形,如下所示。

用于添加绘图线以图我正在使用主GUI线程(使用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:错误线程删除的异步处理程序

如果我错过了使用matplotlib和线程的一些步骤,请告诉我。

0 个答案:

没有答案