【问题标题】:How to use thread with matplotlib on wxpython如何在 wxpython 上使用带有 matplotlib 的线程
【发布时间】:2019-05-16 11:32:43
【问题描述】:

我想为 matplotlib 使用另一个线程。但是当我在脚本下面运行时,它给出了一个错误定时器只能从主线程启动。 任何帮助将不胜感激。

import wx
from threading import Thread
import serial
import threading
import time
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax1 = plt.subplots( )  
def runA():
    print("THREAD")
    while True:
        def mix(i)
            x=[1,3,5]
            y=[13,5,23]
            plt.plot(x,y)
            time.sleep(1)
        ani =animation. FuncAnimation(fig,mix)
        plt.show()

class MyFrame1 ( wx.Frame ):
    def __init__ (self, parent):
        wx.Frame.__init__(self, parent)
        self.SetSizeHints( wx.Defaultsize, wx.DefaultSize)
        bSizer3= wx.BoxSizer(wx.VERTICAL)

        self.button1= wx.Button( self, wx.ID_ANY, "mybutton1", wx.DefaultPosition, wx.DefaultSize, 0)

        bsizer3.Add( self.button1, 1, wx.ALL|wx.EXPAND, 5)

        self.button2= wx.Button( self, wx.ID_ANY, "mybutton2", wx.DefaultPosition, wx.DefaultSize, 0)

        bsizer3.Add( self.button2, 1, wx.ALL|wx.EXPAND, 5)
        self SetSizer( bsizer3)
        self.Layout ()
        self.Centre( wx. BOTH )
# Connect Events
        self.button1.Bind(wx.EVT_BUTTON, self.b1_f )
        self.button2.Bind(wx.EVT_BUTTON, self.b2_f )

    def b1_f( self, event ):
        t2=Thread (target =runA)
        t2.start()

    def b2_f( self, event):
        print("heLLo")

if __name__ == "__main__":
    app = wx.App(False)
    frame=MyFrame1 (None)
    frame.Show(True)
    app.MainLoop()

注意:实际上 wxpython 有自己的绘图库。但我无法成功读取图像并在其上绘制数据。

【问题讨论】:

    标签: python multithreading matplotlib wxpython


    【解决方案1】:

    您问题中的代码存在几个问题。以下行在 wxPython 4.0.4 中不起作用,self.SetSizeHints( wx.Defaultsize, wx.DefaultSize) 并且您为 wx.BoxSizer 使用了不同的名称。关于这个问题,我无法重现您的错误,但我认为问题在于您需要将绘图代码移动到class MyFrame1。一种方法是:

    import wx
    from threading import Thread
    import serial
    import threading
    import time
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    class MyFrame1(wx.Frame):
        def __init__ (self, parent):
            wx.Frame.__init__(self, parent)
            #self.SetSizeHints(wx.Defaultsize, wx.DefaultSize)
            bSizer3= wx.BoxSizer(wx.VERTICAL)
    
            self.button1 = wx.Button(self, wx.ID_ANY, "mybutton1", 
                                     wx.DefaultPosition, wx.DefaultSize, 0)
    
            bSizer3.Add(self.button1, 1, wx.ALL|wx.EXPAND, 5)
    
            self.button2 = wx.Button(self, wx.ID_ANY, "mybutton2", 
                                     wx.DefaultPosition, wx.DefaultSize, 0)
    
            bSizer3.Add(self.button2, 1, wx.ALL|wx.EXPAND, 5)
            self.SetSizer(bSizer3)
            self.Layout()
            self.Centre(wx.BOTH)
    # Connect Events
            self.button1.Bind(wx.EVT_BUTTON, self.b1_f)
            self.button2.Bind(wx.EVT_BUTTON, self.b2_f)
    
        def b1_f( self, event ):
            print('Hello2')
            t2=Thread(target = self.runA)
            t2.start()
    
        def b2_f( self, event):
            print("heLLo")
    
    
        def runA(self):
            fig, ax1 = plt.subplots( )  
            print("THREAD")
            while True:
                def mix(i):
                    x=[1,3,5]
                    y=[13,5,23]
                    plt.plot(x,y)
                    time.sleep(1)
                ani = animation.FuncAnimation(fig,mix)
                plt.show()
    
    if __name__ == "__main__":
        app = wx.App()
        frame=MyFrame1(None)
        frame.Show()
        app.MainLoop()
    

    现在这项工作,但是:

    1 - 您应该考虑将 wxAgg 后端用于matplotlib。您现在使用的后端在您制作绘图、关闭它并再次绘图时会出现非致命错误。此外,它适用于 Win10 和 Linux(Fedora 30),但不适用于 macOS 10.14.4。这是example

    2 - 您需要找到一种方法来停用/激活 button1,因为使用当前的 matplotlib 后端您不能同时拥有两个绘图。因此,在显示绘图时单击按钮会使 GUI 无响应。

    3 - 绘图功能中的计时器使绘图无响应。也许 matplotlib 有另一种方式来控制动画的速度。

    【讨论】:

    • 我意识到将 matplotlib 与 wxpython 一起使用并不是一个好主意。据我所知,它们都在不同的线程上运行。并且有可能产生错误。所以我将我的绘图库转换为 matplotlib 的 wxagg 后端。它通过启用绘制图像和数据解决了我的问题。顺便感谢您的明确回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多