使用Matplotlib,PyQt和Threading进行实时绘图会导致python崩溃

PyTechnic

我一直在努力处理我的Python应用程序,但找不到任何答案。

我有使用Matplotlib小部件的PyQT GUI应用程序。GUI启动一个新线程,该线程处理对mpl小部件的绘制。恐怕我现在正在通过从另一个线程访问导致崩溃的线程访问matplotlib绘图组件而进入竞争状态。

基本上,这就是我的代码:

class Analyzer(QMainWindow, Ui_MainWindow):
  def __init__(self, parent=None):
    self.timer = QTimer()
    super(Analyzer, self).__init__(parent)
    self.setupUi(self)

    self.background = self.mpl.canvas.copy_from_bbox(self.mpl.canvas.ax.bbox)

    self.plotQueue = Queue.Queue()
    self.plotterStarted = False

    self.plotter = Plotter(self.mpl, self.plotQueue)
    self.cam = Cam(self.plotQueue, self.textEdit)
    ...

class Ui_MainWindow(object):
  def setupUi(self, MainWindow):
    ...
    self.mpl = MplWidget(self.centralWidget)
    ...

class MplWidget(QtGui.QWidget):
"""Widget defined in Qt Designer"""
  def __init__(self, parent = None):
    QtGui.QWidget.__init__(self, parent)
    self.canvas = MplCanvas()
    ...

class MplCanvas(FigureCanvas):
"""Class to represent the FigureCanvas widget"""
  def __init__(self):        
    # setup Matplotlib Figure and Axis
    self.fig = Figure()
    self.ax = self.fig.add_subplot(111)

    # initialization of the canvas
    FigureCanvas.__init__(self, self.fig)

    FigureCanvas.updateGeometry(self)

和绘图仪类:

class Plotter():
  def __init__(self, mpl="", plotQueue=""):
    self.mpl = mpl
    self.background = self.mpl.canvas.copy_from_bbox(self.mpl.canvas.ax.bbox)
    self.plotQueue = plotQueue
    ...
  def start(self):
    threading.Thread(target=self.run).start()

  ''' Real time plotting '''
  def run(self):
    while True:
      try:
        inputData = self.plotQueue.get(timeout=1)

        # Go through samples
        for samples in inputData:
            self.line, = self.mpl.canvas.ax.plot(x, y, animated=True, label='Jee')

            for sample in samples:
                x.append(sample['tick'])
                y.append(sample['linear'])

            self.line.set_data(x,y)
            self.mpl.canvas.ax.draw_artist(self.line)
            self.mpl.canvas.blit(self.mpl.canvas.ax.bbox)
         ...

因此,我将mpl和plotQueue传递给Plotter类对象。PlotQueue填充在Cam类中,该类处理来自外部硬件的传入数据。绘图仪读取plotQueue,对其进行处理并为mpl调用绘图。

但这是访问mpl的线程安全方法吗?如果没有,我该怎么办?任何提示对此表示赞赏。


编辑1。

我在注释中建议在主线程中添加QTimer以处理绘图。稍作调整后,我就可以正常工作了。

class Analyzer(...):
  def __init__(self, parent=None):
    QObject.connect(self.timer, SIGNAL("timeout()"), self.periodicCall)

  def periodicCall(self):
    self.plotter.draw()

  def startButton(self):
    self.timer.start(10)

非常感谢您的有用评论。

三菠萝

如果程序中的matplotlib使用的是QT后端(我认为是因为您将其嵌入到Qt应用程序中),那么绘图将在您从中调用matplotlib命令的线程中完成。这将是一个问题,因为Qt要求所有绘图都是从主线程完成的。因此,我敢肯定您不能简单地解决它。(如果您使用的是GTK,则可以在线程中执行与GUI相关的操作时使用gtk锁来防止主进程与GUI交互,但是Qt在v4及更高版本中摆脱了它们的类似锁)。

您有几种选择:

  1. 尝试分离出matplotlib的绘图部分(可能甚至无法实现?),并通过发送以下事件来使其在主线程中运行: QApplication.postEvent()

  2. 除了使用线程外,还可以在主线程中使用回调(可以使用QTimer或在程序空闲时定期调用)。由于Python GIL仍然会阻止真正的多线程行为,因此这种可能性不会影响应用程序的性能。

  3. 使用其他绘图库。几天我看了看PyQtGraph,看来进展顺利。从我的简要信息看,我认为它可以使用来为您处理所有这些问题RemoteGraphicsView这将启动第二个过程来执行CPU密集型绘图工作,从而绕过上述Python GIL问题。如果您有兴趣,请查看他们提供的示例

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在同一图上使用Python和Matplotlib显示实时烛台

来自分类Dev

用numpy分隔数组以在python中使用matplotlib进行绘图

来自分类Dev

使用backgroundSessionConfiguration和NSURLSessionUploadTask上传会导致应用崩溃

来自分类Dev

使用pandas和str.strip导致Python崩溃

来自分类Dev

使用Matplotlib进行绘图会产生-90旋转的绘图-Python

来自分类Dev

使用system()与Gnuplot进行绘图会导致错误:文件不可读

来自分类Dev

Python Matplotlib在绘图时崩溃

来自分类Dev

python matplotlib和PyQT用于多选项卡绘图-导航

来自分类Dev

使用滑块进行错误绘图(python matplotlib)

来自分类Dev

使用滑块在Matlab中进行实时绘图

来自分类Dev

在实时绘图期间在matplotlib中移动x轴(python)

来自分类Dev

Matplotlib和PyQt5绘图图

来自分类Dev

使用Matplotlib Python进行绘图时跳过缺少的时间戳记

来自分类Dev

PyQt将图像从URL加载到QPixmap会导致冻结和崩溃

来自分类Dev

使用Matplotlib进行实时绘图的Python

来自分类Dev

使用Matplotlib的实时图形不显示绘图

来自分类Dev

用numpy分隔数组以在python中使用matplotlib进行绘图

来自分类Dev

无法使用Matplotlib进行绘图

来自分类Dev

使用Matplotlib进行绘图会产生-90旋转的绘图-Python

来自分类Dev

Matplot lib不使用PyQt进行绘图

来自分类Dev

Python Matplotlib在绘图时崩溃

来自分类Dev

在Python 3 pylab中使用Matplotlib进行绘图:Tkinter和Qt FontManager错误

来自分类Dev

如何使用matplotlib.animation连续流动态增长列表中的数据点以进行实时绘图?

来自分类Dev

使用滑块在Matlab中进行实时绘图

来自分类Dev

使用mysql和流传感器数据进行d3实时图形绘图

来自分类Dev

使用 pandas 和 matplotlib 绘图

来自分类Dev

使用 collect 和 flatten 进行断言会导致错误(groovy)

来自分类Dev

使用 twgl 和 framebuffers 会导致 GPU 内存泄漏并导致浏览器崩溃(附上 plunkr)

来自分类Dev

我如何使用 Matplotlib 更新实时绘图

Related 相关文章

  1. 1

    在同一图上使用Python和Matplotlib显示实时烛台

  2. 2

    用numpy分隔数组以在python中使用matplotlib进行绘图

  3. 3

    使用backgroundSessionConfiguration和NSURLSessionUploadTask上传会导致应用崩溃

  4. 4

    使用pandas和str.strip导致Python崩溃

  5. 5

    使用Matplotlib进行绘图会产生-90旋转的绘图-Python

  6. 6

    使用system()与Gnuplot进行绘图会导致错误:文件不可读

  7. 7

    Python Matplotlib在绘图时崩溃

  8. 8

    python matplotlib和PyQT用于多选项卡绘图-导航

  9. 9

    使用滑块进行错误绘图(python matplotlib)

  10. 10

    使用滑块在Matlab中进行实时绘图

  11. 11

    在实时绘图期间在matplotlib中移动x轴(python)

  12. 12

    Matplotlib和PyQt5绘图图

  13. 13

    使用Matplotlib Python进行绘图时跳过缺少的时间戳记

  14. 14

    PyQt将图像从URL加载到QPixmap会导致冻结和崩溃

  15. 15

    使用Matplotlib进行实时绘图的Python

  16. 16

    使用Matplotlib的实时图形不显示绘图

  17. 17

    用numpy分隔数组以在python中使用matplotlib进行绘图

  18. 18

    无法使用Matplotlib进行绘图

  19. 19

    使用Matplotlib进行绘图会产生-90旋转的绘图-Python

  20. 20

    Matplot lib不使用PyQt进行绘图

  21. 21

    Python Matplotlib在绘图时崩溃

  22. 22

    在Python 3 pylab中使用Matplotlib进行绘图:Tkinter和Qt FontManager错误

  23. 23

    如何使用matplotlib.animation连续流动态增长列表中的数据点以进行实时绘图?

  24. 24

    使用滑块在Matlab中进行实时绘图

  25. 25

    使用mysql和流传感器数据进行d3实时图形绘图

  26. 26

    使用 pandas 和 matplotlib 绘图

  27. 27

    使用 collect 和 flatten 进行断言会导致错误(groovy)

  28. 28

    使用 twgl 和 framebuffers 会导致 GPU 内存泄漏并导致浏览器崩溃(附上 plunkr)

  29. 29

    我如何使用 Matplotlib 更新实时绘图

热门标签

归档