GUI freezes while charting with matplotlib

倖福魔咒の 提交于 2019-12-13 04:26:26

问题


I have a GUI written in wxPython (some extra information can be found in a different question). The GUI has indicators(charts, text, etc) and controls(buttons, radioboxes, etc. Every so often I get new data to plot. Depends on the size of that data set it can take up to 20 seconds to produce the graph and draw it. During this time the GUI controls are not responsive since the GUI thread is busy with charting.

How do I make GUI controls always responsive regardless of what is the size of data set I am plotting?


回答1:


Here is the solution to this problem. Briefly,

  1. plot in a separate thread
  2. save the figure into a buffer (a byte stream with io.Bytes())
  3. retrieve the buffer and show as a bitmap in your GUI.

See the code below.

    frame = wx.Frame.__init__(self, None, wx.ID_ANY, "", size = (1200,800))#, style= wx.SYSTEM_MENU | wx.CAPTION)
    self.panel = wx.Panel(self, wx.ID_ANY, style=wx.BORDER_THEME, size = (1200,800))

    #bmp1 = wx.Bitmap.FromRGBA(100, 100, red=255, alpha=0)
    self.bitmap1 = wx.StaticBitmap(self.panel)
    self.bitmap2 = wx.StaticBitmap(self.panel)

    sizer = wx.GridBagSizer(hgap = 0, vgap = 0)#(13, 11)
    sizer.Add(self.bitmap1, pos=(0,0),  flag = wx.ALL)#, flag=wx.TOP|wx.RIGHT) FIXIT so the sidebar is closer to the graph
    sizer.Add(self.bitmap2, pos=(1,0),  flag = wx.ALL)#,flag=wx.TOP|wx.RIGHT)


    def buf2wx (buf):
        import PIL
        image = PIL.Image.open(buf)
        width, height = image.size
        return wx.Bitmap.FromBuffer(width, height, image.tobytes())
    #access the buffer which was created in a different thread 
    #or use socket to retrieve it from a remote server or 
    #whatever you might want to do.
    buf = get_buf_from_somewhere() 

    self.bitmap1.SetBitmap(buf2wx(buf))
    self.bitmap2.SetBitmap(buf2wx(buf))



    self.panel.SetSizer(sizer)
    self.Layout()
    self.panel.Layout()
    self.Fit()

The piece of code running in a different thread or even on a remote server. This code will generate a plot and save it in a file that can be read by GUI or transferred elsewhere.

def plot():
    from matplotlib import pyplot as plt
    import io
    from numpy import random
    plt.figure()
    b = random.rand(100,)
    plt.subplot(311)
    plt.plot(b)
    b = random.rand(100,)
    plt.subplot(312)
    plt.plot(b)
    b = random.rand(100,)
    plt.subplot(313)
    plt.plot(b)
    plt.title("test")
    buf = io.BytesIO()
    plt.savefig(buf, format='jpg')
    buf.seek(0)
    return buf


来源:https://stackoverflow.com/questions/52206292/gui-freezes-while-charting-with-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!