如何解决PySimpleGUI中的交互式matplotlib图
我正在尝试使RectangleSelector表单matplotlib.widgets与PySimpleGUI一起使用。 我将测试代码基于接受的答案on this question中显示的RectangleSelector演示。
我正在PySimpleGUI中显示该图,但它不是交互式的。在PySimpleGUI中甚至有可能具有交互式matplotlib小部件?
import PySimpleGUI as sg
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
from matplotlib.widgets import RectangleSelector
import matplotlib
matplotlib.use('TkAgg')
xdata = np.linspace(0,9*np.pi,num=301)
ydata = np.sin(xdata)
fig,ax = plt.subplots()
line,= ax.plot(xdata,ydata)
def draw_figure(canvas,figure):
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 line_select_callback(eclick,erelease):
x1,y1 = eclick.xdata,eclick.ydata
x2,y2 = erelease.xdata,erelease.ydata
rect = plt.Rectangle( (min(x1,x2),min(y1,y2)),np.abs(x1-x2),np.abs(y1-y2) )
ax.add_patch(rect)
rs = RectangleSelector(ax,line_select_callback,drawtype='Box',useblit=False,button=[1],minspanx=5,minspany=5,spancoords='pixels',interactive=True)
layout = [[sg.Canvas(key="-CANVAS-")]]
window = sg.Window('test',layout,finalize=True,element_justification='center',font='Helvetica 16')
draw_figure(window["-CANVAS-"].TKCanvas,fig)
event,values = window.read()
编辑:感谢MikeyB的指针,我现在有了以下代码,该代码显示了一个交互式绘图,但是仍然无法绘制矩形。回调函数似乎没有触发。下面的新代码:
import PySimpleGUI as sg
import numpy as np
from matplotlib.widgets import RectangleSelector
import matplotlib.figure as figure
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg,NavigationToolbar2Tk
# instantiate matplotlib figure
fig = figure.figure()
ax = fig.add_subplot(111)
DPI = fig.get_dpi()
fig.set_size_inches(505 * 2 / float(DPI),707 / float(DPI))
# ------------------------------- This is to include a matplotlib figure in a Tkinter canvas
def draw_figure_w_toolbar(canvas,fig,canvas_toolbar):
if canvas.children:
for child in canvas.winfo_children():
child.destroy()
if canvas_toolbar.children:
for child in canvas_toolbar.winfo_children():
child.destroy()
figure_canvas_agg = figureCanvasTkAgg(fig,master=canvas)
figure_canvas_agg.draw()
toolbar = Toolbar(figure_canvas_agg,canvas_toolbar)
toolbar.update()
figure_canvas_agg.get_tk_widget().pack(side='right',fill='both',expand=1)
def line_select_callback(eclick,np.abs(y1-y2) )
print(rect)
ax.add_patch(rect)
class Toolbar(NavigationToolbar2Tk):
def __init__(self,*args,**kwargs):
super(Toolbar,self).__init__(*args,**kwargs)
# ------------------------------- PySimpleGUI CODE
layout = [
[sg.B('start',key='start')],[sg.Canvas(key='controls_cv')],[sg.Column(
layout=[
[sg.Canvas(key='fig_cv',# it's important that you set this size
size=(500 * 2,700)
)]
],background_color='#DAE0E6',pad=(0,0)
)],]
window = sg.Window('Test',layout)
while True:
event,values = window.read()
print(event,values)
if event == sg.WIN_CLOSED:
break
elif event == 'start':
x = np.linspace(0,2 * np.pi)
y = np.sin(x)
line,= ax.plot(x,y)
rs = RectangleSelector(ax,interactive=True)
draw_figure_w_toolbar(window['fig_cv'].TKCanvas,window['controls_cv'].TKCanvas)
window.close()
解决方法
在PySimpleGUI中甚至有可能具有交互式matplotlib小部件吗?
是的
项目GitHub上的演示程序展示了如何制作交互式Matplotlib绘图。
您需要将控件嵌入到窗口中。
,您需要添加
fig.canvas.draw()
如果您希望在回调触发后更新绘图,请转到您的回调函数!
这是您的代码的更新版本,可以正常工作:
import PySimpleGUI as sg
import numpy as np
from matplotlib.widgets import RectangleSelector
import matplotlib.figure as figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
import matplotlib.pyplot as plt
# instantiate matplotlib figure
fig = figure.Figure()
ax = fig.add_subplot(111)
DPI = fig.get_dpi()
fig.set_size_inches(505 * 2 / float(DPI),707 / float(DPI))
# ------------------------------- This is to include a matplotlib figure in a Tkinter canvas
def draw_figure_w_toolbar(canvas,fig,canvas_toolbar):
if canvas.children:
for child in canvas.winfo_children():
child.destroy()
if canvas_toolbar.children:
for child in canvas_toolbar.winfo_children():
child.destroy()
figure_canvas_agg = FigureCanvasTkAgg(fig,master=canvas)
figure_canvas_agg.draw()
toolbar = Toolbar(figure_canvas_agg,canvas_toolbar)
toolbar.update()
figure_canvas_agg.get_tk_widget().pack(side='right',fill='both',expand=1)
def line_select_callback(eclick,erelease):
x1,y1 = eclick.xdata,eclick.ydata
x2,y2 = erelease.xdata,erelease.ydata
rect = plt.Rectangle( (min(x1,x2),min(y1,y2)),np.abs(x1-x2),np.abs(y1-y2) )
print(rect)
ax.add_patch(rect)
fig.canvas.draw()
class Toolbar(NavigationToolbar2Tk):
def __init__(self,*args,**kwargs):
super(Toolbar,self).__init__(*args,**kwargs)
# ------------------------------- PySimpleGUI CODE
layout = [
[sg.B('start',key='start')],[sg.Canvas(key='controls_cv')],[sg.Column(
layout=[
[sg.Canvas(key='fig_cv',# it's important that you set this size
size=(500 * 2,700)
)]
],background_color='#DAE0E6',pad=(0,0)
)],]
window = sg.Window('Test',layout)
while True:
event,values = window.read()
print(event,values)
if event == sg.WIN_CLOSED:
break
elif event == 'start':
x = np.linspace(0,2 * np.pi)
y = np.sin(x)
line,= ax.plot(x,y)
rs = RectangleSelector(ax,line_select_callback,drawtype='box',useblit=False,button=[1],minspanx=5,minspany=5,spancoords='pixels',interactive=True)
draw_figure_w_toolbar(window['fig_cv'].TKCanvas,window['controls_cv'].TKCanvas)
window.close()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。