Я использую 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 с потоками.