【发布时间】:2020-11-19 04:25:52
【问题描述】:
我正在创建一个 GUI,以允许用户查看光谱仪的“实时视图”,其中数据从光谱仪获取并绘制在 Matplotlib 中以显示在 GUI 窗口中。 GUI 还有一些其他按钮,允许用户使用其他功能(不相关但只是背景)。
我已经让实时视图在 matplotlib 中使用 while 循环并清除数据以重新绘制:
while True:
data = ccs.take_data(num_avg=3) # spectrometer function
norm = (data[0]-dark[0])/(light[0]-dark[0]) # some calcs.
plt.plot(data[1],norm)
plt.axis([400,740,0,1.1])
plt.grid(color='w', linestyle='--')
plt.xlabel('Wavelength [nm]')
plt.ylabel('Normalized Intesity')
plt.pause(0.1)
plt.cla()
下一步是在 PySimpleGUI 中显示此图。比expexted更难...如果用户按下“更新”按钮,我可以使用 PySimpleGUI 中的一些演示代码来显示和更新单个图形:
from instrumental.drivers.spectrometers import thorlabs_ccs
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
import matplotlib, time, threading
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
def fig_maker(ccs, dark, sub):
plt.clf()
plt.close()
data = ccs.take_data(num_avg=3)
norm = (data[0]-dark[0])/(sub[0]-dark[0])
plt.plot(data[1],norm,c='r')
plt.axis([400,750,0,1.1])
plt.grid(color='w', linestyle='--')
plt.xlabel('Wavelength [nm]')
plt.ylabel('Normalized Intesity')
return plt.gcf()
def draw_figure(canvas, figure, loc=(0, 0)):
figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
figure_canvas_agg.draw()
figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
return figure_canvas_agg
def delete_fig_agg(fig_agg):
fig_agg.get_tk_widget().forget()
plt.close('all')
if __name__ == '__main__':
... some code ...
# define the window layout
layout = [[sg.Button('update')],
[sg.Text('Plot test', font='Any 18')],
[sg.Canvas(size=(500,500), key='canvas')] ]
# create the form and show it without the plot
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',
layout, finalize=True)
fig_agg = None
while True:
event, values = window.read()
if event is None: # if user closes window
break
if event == "update":
if fig_agg is not None:
delete_fig_agg(fig_agg)
fig = fig_maker(ccs,dark,sub)
fig_agg = draw_figure(window['canvas'].TKCanvas, fig)
window.close()
现在是有趣的部分(我似乎无法让它工作)。我希望情节总是像我使用 matplotlib 那样更新,这样用户就不必按“更新”。使用PySimpleGUI long_task threaded example 是我的程序开始失败的地方。除了在 Python 关闭脚本之前打印到 Debug I/O 声明 *** Faking Timeout *** 之外,我实际上没有抛出任何错误。
我什至只是尝试做一个 10 次迭代的 for 循环,而不是连续的 while 循环:
from instrumental.drivers.spectrometers import thorlabs_ccs
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
import matplotlib, time, threading
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
def long_function_thread(window, ccs, dark, sub):
for i in range(10):
fig = fig_maker(ccs, dark, sub)
fig_agg = draw_figure(window['canvas'].TKCanvas, fig)
window.write_event_value('-THREAD PROGRESS-', i)
time.sleep(1)
delete_fig_agg(fig_agg)
time.sleep(0.1)
window.write_event_value('-THREAD DONE-', '')
def long_function(window, ccs, dark, sub):
print('In long_function')
threading.Thread(target=long_function_thread, args=(window, ccs, dark, sub), daemon=True).start()
def fig_maker(ccs, dark, sub):
plt.clf()
plt.close()
data = ccs.take_data(num_avg=3)
norm = (data[0]-dark[0])/(sub[0]-dark[0])
plt.plot(data[1],norm,c='r')
plt.axis([400,750,0,1.1])
plt.grid(color='w', linestyle='--')
plt.xlabel('Wavelength [nm]')
plt.ylabel('Normalized Intesity')
return plt.gcf()
def draw_figure(canvas, figure, loc=(0, 0)):
figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
figure_canvas_agg.draw()
figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
return figure_canvas_agg
def delete_fig_agg(fig_agg):
fig_agg.get_tk_widget().forget()
plt.close('all')
if __name__ == '__main__':
... some code ...
# define the window layout
layout = [[sg.Button('Go')],
[sg.Text('Plot test', font='Any 18')],
[sg.Canvas(size=(500,500), key='canvas')] ]
# create the form and show it without the plot
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',
layout, finalize=True)
fig_agg = None
while True:
event, values = window.read()
if event is None or event == 'Exit':
break
if event == 'Go':
print('Calling plotter')
long_function(window, ccs, dark, sub)
print('Long function has returned from starting')
elif event == '-THREAD DONE-':
print('Your long operation completed')
window.close()
关于长描述和代码转储的应用,但我认为这是最简单的解释方式。任何有关此问题的帮助或链接将不胜感激。
如果有人想尝试运行我的脚本,这应该只是生成一个随机图
def random_fig_maker():
plt.scatter(np.random.rand(1,10),np.random.rand(1,10))
return plt.gcf()
【问题讨论】:
标签: python-3.x python-2.7 matplotlib