PySimpleGUI中的交互式matplotlib图

如何解决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绘图。

https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_Embedded_Toolbar.py

您需要将控件嵌入到窗口中。

,

您需要添加

    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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?