创建matplotlib绘图会在我的tk GUI中引发运行时错误

2024-09-30 20:20:36 发布

您现在位置:Python中文网/ 问答频道 /正文

TLDR:如果没有我的tkinter图形用户界面,即使我的图形用户界面在主线程中运行,matplotlib函数在一个单独的线程中调用,我也无法从matplotlib保存我的图形。在


我正在尝试用python绘制图形。我正在使用matplotlib。我已经成功地绘制了我的第一张图,但是我面临的问题似乎与我用tkinter编写的GUI有关。我用的是Python3。在

简而言之,我的代码读取二进制文件并为每个二进制文件生成一个图形。所以在我的函数read_files中,当run是它自己的线程时,我有一个for循环来读取二进制文件并创建一个绘图并保存绘图。在

运行脚本时,我收到以下错误:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python34\lib\threading.py", line 911, in _bootstrap_inner
    self.run()
  File "C:\Python34\lib\threading.py", line 859, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Python34\Projects\PurgePressureAnalysis\GUI.py", line 77, in callback
    self.function_chain_v1()
  File "C:\Python34\Projects\PurgePressureAnalysis\GUI.py", line 101, in function_chain_v1
    (func.__func__)(self.infoObj)
  File "C:\Python34\Projects\PurgePressureAnalysis\lib\features.py", line 96, in waveform_analysis
    Graph.plot_lt_wvfrm(case_wvfrm)
  File "C:\Python34\Projects\PurgePressureAnalysis\lib\graph.py", line 18, in plot_lt_wvfrm
    fig = plt.figure()
  File "C:\Python34\lib\site-packages\matplotlib\pyplot.py", line 527, in figure
    **kwargs)
  File "C:\Python34\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 84, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "C:\Python34\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 101, in new_figure_manager_given_figure
    icon_img = Tk.PhotoImage(file=icon_fname)
  File "C:\Python34\lib\tkinter\__init__.py", line 3421, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Python34\lib\tkinter\__init__.py", line 3377, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
RuntimeError: main thread is not in main loop

读完这篇question,我知道这个问题与tkinter有关,而不是{}。我确认了这一点,因为我在抛出错误之前成功地保存了我的绘图。在

以下是我的代码的相关部分(为了简化起见,删去了一些部分):

这是在我的GUI中单击按钮时调用的函数。在

^{pr2}$

这个函数调用我的绘图和保存函数。此函数在Thread-1中调用。(为了简单起见,部分部件被切除):

@staticmethod
def waveform_analysis(infoObj):
    for case in infoObj.filelist:
        wvfrm_per_case = []
        case_wvfrm = []
        for index in range(len(case)):
            case_wvfrm = read_binary() #simplification of what is really happening
        Convert.convert_wvfrm_to_csv(case_wvfrm, a)
        Graph.plot_lt_wvfrm(case_wvfrm)

    return infoObj.output

这是在Thread-1中调用的plot函数

@staticmethod
    def plot_lt_wvfrm(wvfrms):
        fig = plt.figure()
        ax1 = plt.subplot2grid((2,1), (0,0), rowspan = 1)
        ax2 = plt.subplot2grid((2,1), (1,0), rowspan = 1)

        x, y = read(channel_y, purge_y, wvfrms)
        for ys in y:
            ax1.plot(x, ys)

        x, y = read(purge_y, len(wvfrms[0]), wvfrms)
        for ys in y:
            ax2.plot(x, ys)

        plt.savefig('C:\\Users\\dzhao\\Desktop\\' + str(wvfrms[0][1]) + '.png')

我所做的:

我试着把这个Graph.plot_lt_wvfrm放到另一个线程中(因此是一个线程中的一个线程),并且成功地保存了.png文件,但是这个与tkinter相关的错误仍然发生。我已经研究过这个question中的队列,但是我不敢尝试这个,因为我不确定队列是否能解决这个错误的根本原因。我还尝试将一些与matplotlib相关的函数移到主线程中(比如'fig=plt.图())但这没用。在

我只知道这是一个与线程相关的问题,因为matplotlib也使用tkinter并且他们在某个地方为某些事情而争吵。在

是的。。。从我的分析有多模糊,你可以看出我对这个问题的理解。在

我如何保持我的图形用户界面工作(防止这个RunTimeError出现),但也让我的图形制作+保存功能工作?在

我看过的其他问题是:contextcontext2context3context 4


Tags: 函数inpyselfplotmatplotlibtkinterlib