TLDR :即使我的GUI在主线程和{{1}中运行,我也无法在matplotlib
没有tkinter
GUI的情况下保存我的图表函数在一个单独的线程中调用。
我正在尝试在python中制作图表。我正在使用matplotlib
。我已经成功绘制了我的第一张图,但是我面临的问题似乎与matplotlib
中编写的GUI有关。我正在使用Python3。
简而言之,我的代码读取二进制文件并为每个二进制文件创建一个图形。所以在我的函数tkinter
中,运行时它是自己的线程,我有一个for循环读取二进制文件并创建一个图并保存图。
运行我的脚本后,我收到此错误:
read_files
阅读此question后,我知道问题与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
有关,而与tkinter
无关。我已经证实了这一点,因为我在错误被抛出之前成功保存了我的情节。
以下是我的代码的相关部分(为简化起见,部分内容已删除):
当我点击GUI中的按钮时,这是调用的函数。
matplotlib
此函数调用我的绘图和保存功能。在Thread-1中调用此函数。 (为简单起见,部分内容已被删除):
def Search(self):
def callback():
try:
self.function_chain_v1()
self.add_text('Search Complete')
except OSError as e:
handle_exceptions()
self.t = threading.Thread(target = callback)
self.t.start()
这是绘图函数这个函数在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
我尝试了什么:
我已经尝试将此@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')
放入另一个线程(因此线程中的线程)并且.png文件已成功保存,但仍会出现与Graph.plot_lt_wvfrm
相关的错误。我已经从这个question查看了队列,但是我很想尝试这个,因为我不确定队列是否能解决这个错误的根本原因。我也尝试将一些与tkinter
相关的函数移到主线程中(比如`fig = plt.figure()),但这没有做任何事情。
我所知道的是,这是一个与线程相关的问题,因为matplotlib
也使用了matplotlib
,并且某个地方正在争夺某些东西。
是的......你可以通过我的分析是多么模糊来告诉我对这个问题的理解。
如何保持GUI工作(防止显示此tkinter
),同时让我的图表制作+保存功能有效?