使用 matplotlib 绘制图表时 GUI 冻结 [英] GUI freezes while charting with matplotlib

查看:44
本文介绍了使用 matplotlib 绘制图表时 GUI 冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 wxPython 编写的 GUI(一些额外的信息可以在不同的问题中找到).GUI 有指标(图表、文本等)和控件(按钮、单选框等.我经常会得到新数据来绘制.根据该数据集的大小,生成图表可能需要长达 20 秒的时间和绘制它.在此期间,GUI 控件没有响应,因为 GUI 线程正忙于绘制图表.

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.

无论我绘制的数据集有多大,如何使 GUI 控件始终响应?

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

推荐答案

这里是这个问题的解决方案.简而言之,

Here is the solution to this problem. Briefly,

  1. 在单独的线程中绘图
  2. 将图形保存到缓冲区(带有 io.Bytes() 的字节流)
  3. 检索缓冲区并在您的 GUI 中显示为位图.

查看下面的代码.

    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()

在不同线程甚至远程服务器上运行的一段代码.此代码将生成一个绘图并将其保存在一个可由 GUI 读取或传输到其他地方的文件中.

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

这篇关于使用 matplotlib 绘制图表时 GUI 冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆