matplotlib 在Python PySimpleGUI中嵌入使用用户输入绘制的图形

lyr7nygr  于 2023-01-17  发布在  Python
关注(0)|答案(1)|浏览(160)

我正在为一个项目使用PySimpleGui制作一个GUI。下面是复制关键结构的代码-它由两列组成,LHS列有两个选项卡。在其中一个选项卡中,我要求GUI用户输入,以便绘制一个图形,该图形将嵌入到同一个选项卡中。如果提交不同的输入,则会迭代更新。因此,我要求为方程b\*x^2 + a\*x提供系数b和a。我使用的是matplotlib.use('TkAgg)FigureCanvas TkAgg,但在我希望绘制曲线图的代码行中,并更新GUI
图_画布_agg =图画布TkAgg(图,画布)
我得到错误:属性错误:'Canvas' object has no attribute 'set_canvas'。请我能得到一些关于如何修复的帮助吗?我提供了下面的GUI代码,然后是一个绘图仪类,其中的错误是在类方法draw_plot。这个类是在一个单独的脚本和导入到主GUI脚本,谢谢!!

##### MAIN GUI Script ####

from GUI_helpers import * # this was where the Plotter class was stored
import PySimpleGUI as sg

profile = Plotter()

def refresh(window):
            window.refresh()

sg.theme("Black")
sg.set_options(font=("Avenir Next", 16))

tab_1 = [  

        [sg.Text("PLOTTER FOR bx^2 + ax",expand_x=True,justification="center",font =("Avenir Next", 16,'bold'))],
    [sg.Text("Coefficeint for x (a)",font =("Avenir Next", 14)),sg.Push(),
        sg.Input(key='-x-',  size=(3, 1)),
        sg.Button("Submit",key = 'x',font =("Avenir Next", 14))],
    [sg.Text("Coefficient for x^2 (b) ",font =("Avenir Next", 14)), sg.Push(),
        sg.Input(key='-x_squared-', size=(3, 1),),
        sg.Button("Submit",key = 'x_squared', font =("Avenir Next", 14))],
   
    [sg.Canvas(size=(20,20), key='plot-canvas')]]

tab_2 = [
    [sg.Text("RANDOM TEXT",expand_x=True,justification="center",font =("Avenir Next", 16,'bold'))],
    [sg.T(' '*5),sg.Button("RANDOM BUTTON", key='random_1',size=(20,1))],
    [sg.T(' '*5),sg.Button("RANDOM BUTTON", key='random_2',size=(20,1))],
    
]
side_1 = [[sg.TabGroup([[sg.Tab('Tab 1', tab_1),
                    sg.Tab('Tab 2', tab_2)]], tab_location='centertop', border_width=5,size= (300,780),enable_events=True)]]  
        
side_2 = [[sg.Text("SIDE 2 HERE:", expand_x=True, expand_y=True)]]

layout = [[sg.Column(side_1, element_justification='top', size= (320,900),justification='center'),
        sg.VSeperator(),
        sg.Column(side_2, expand_x=True, expand_y=True,size= (1100,900),), 
    ]]

window = sg.Window("Test GUI", layout, resizable=True, finalize=True, use_default_focus=False, return_keyboard_events=True)

refresh_thread = None
fig = None
fig_agg = None

while True:
    
    event, values = window.read()
    
    if event  == 'x': 
        if fig_agg is not None:
                    profile.delete_plot(fig_agg)
        profile.update_x(values['-x-'])
        fig = profile.update_plot(window)
        fig_agg = profile.draw_plot(window['plot-canvas'].TKCanvas, fig)
        window.refresh()

    if event  == 'x_squared': 
        if fig_agg is not None:
                profile.delete_plot(fig_agg)
        profile.update_xsquared(values['-x_squared-'])
        fig = profile.update_plot(window)
        fig_agg = profile.draw_plot(window['plot-canvas'].TKCanvas, fig)
        window.refresh()


window.close()

print('Transfer ended')

###### PLOTTER CLASS (separate script) #####

import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class Plotter:

    def __init__(self): 

        self.a = 0
        self.b = 0

    def update_plot(self,window):

        x_axis =  np.linspace(-10,10)
        x_comp = [self.a * x for x in x_axis]
        x2_comp = [self.b*(x**2) for x in x_axis]
        y_axis = np.add(x_comp,x2_comp)

        plt.ioff()
        plt.plot(x_axis,y_axis)
        plt.xlabel('x')
        plt.ylabel('bx^2 + ax')
        return plt.gcf()

    def draw_plot(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_plot(fig_agg):
        
        fig_agg.get_tk_widget().forget()
        plt.close('all')

    def update_x(self, state):
        self.a= float(state)

    def update_xsquared(self,state):
        self.b = float(state)

我也愿意接受其他的方法来嵌入图形用户界面中的情节!

f8rj6qna

f8rj6qna1#

它是由传递给示例的方法时的错误参数引起的。

def draw_plot(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_plot(fig_agg):
        
        fig_agg.get_tk_widget().forget()
        plt.close('all')

通常,方法的第一个参数叫做self,这只是一个约定:self这个名字对Python来说绝对没有什么特殊意义。
示例的Method中的参数应该从self开始,所以上面的代码修改为

def draw_plot(self, 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_plot(self, fig_agg):

        fig_agg.get_tk_widget().forget()
        plt.close('all')

相关问题