Pysimplegui 不清除 matplotlib 图 canvas

Pysimple GUI not clearing matplotlib graph canvas

上下文:之前发布过类似的问题,现在我不得不使用单选按钮而不是功能列表。原因是当我输入我的文件进行处理时,图表的输入变量将在此时定义,而不是在代码的前面,所以唯一的方法是使用单选按钮,这样我就可以添加函数输入这里的参数。

问题:我的问题是当我点击单选按钮时,之前的图表没有被清除,新的图表打印在原来的图表下面。请有人帮忙 - 谢谢!

此处的最小代码示例:

import PySimpleGUI as sg
import time
import os
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.ticker import NullFormatter  
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
sg.theme('Dark')

def PyplotSimple():
    import numpy as np
    import matplotlib.pyplot as plt
    t = np.arange(0., 5., 0.2)          

    plt.plot(t, t, 'r--', t, t ** 2, 'bs', t, t ** 3, 'g^')

    fig = plt.gcf()  # get the figure to show
    return fig

def PyplotSimple2():
    import numpy as np
    import matplotlib.pyplot as plt
    t = np.arange(0., 5., 0.2)        
    plt.plot(t, t, 'r--', t, t ** 2, 'b--', t, t ** 3, 'b--')

    fig = plt.gcf()  # get the figure to show
    return fig

def draw_plot():
    plt.plot([0.1, 0.2, 0.5, 0.7])
    fig = plt.gcf()  # get the figure to show
    return fig



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 delete_figure_agg(figure_agg):
    figure_agg.get_tk_widget().forget()
    plt.close('all')


layout= [
    [sg.Text('my GUI', size=(40,1),justification='c', font=("Arial 10"))],
    [sg.Text('Browse to file:'), sg.Input(size=(40,1), key='input'),sg.FileBrowse (key='filebrowse')],

    [sg.Button('Process' ,bind_return_key=True), 
     sg.Radio('1',key= 'RADIO1',group_id='1', enable_events = True,default=False, size=(10,1)),
          sg.Radio('2', key= 'RADIO2',group_id='1',enable_events = True, default=False, size=(10,1)),
           sg.Radio('3', key='RADIO3',group_id='1',enable_events = True, default=False, size=(12,1))],

    [sg.Canvas(size=(200,200), background_color='white',key='-CANVAS-')],
    [sg.Exit()]] 


window = sg.Window('my gui', layout, grab_anywhere=False, finalize=True)
#window.Maximize()
figure_agg = None
# The GUI Event Loop

while True:
    event, values = window.read()
    #print(event, values)                  # helps greatly when debugging
    if event in (sg.WIN_CLOSED, 'Exit'):             # if user closed window or clicked Exit button
        break
          
    if figure_agg:
        delete_figure_agg(figure_agg)
        figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
    if event == 'Process':
        #my function here 
        #the output of this function will decide the inputs to the graph which is why i need to use radio buttons
        sg.popup('Complete - view graphs',button_color=('#ffffff','#797979'))
    
    if event ==  'RADIO1':
        fig= PyplotSimple()
        figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)

    if event ==  'RADIO2':
        fig= PyplotSimple2()
        figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
        
    
    if event ==  'RADIO3':
        fig= draw_plot()
        figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
  
    
    elif event == 'Exit':
        break

window.close()

在绘制新图形或坐标轴之前,您可能需要方法 cla()clf() 来清除图形。在 Matplotlib 中找到它们。

没有必要在函数 PyplotSimplePyplotSimple2 中执行以下导入。

    import numpy as np
    import matplotlib.pyplot as plt

此处,删除后再次创建figure_agg。 删除 comment-marked 行。

    if figure_agg:
        delete_figure_agg(figure_agg)
        #figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)

实际上

  • 当 draw_figure 调用
  • 时,在你的 PSG canvas 上又添加了一个 canvas
  • 调用 delete_figure_agg 时未删除 canvas,只是忘记在 pack

这是另一个示例,展示了我如何在 PSG 上使用 matplotlib 图 canvas。

import math

from matplotlib import use as use_agg
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt

import PySimpleGUI as sg

# Use Tkinter Agg
use_agg('TkAgg')

# PySimplGUI window
layout = [[sg.Graph((640, 480), (0, 0), (640, 480), key='Graph')]]
window = sg.Window('Matplotlib', layout, finalize=True)

# Default settings for matplotlib graphics
fig, ax = plt.subplots()

# Link matplotlib to PySimpleGUI Graph
canvas = FigureCanvasTkAgg(fig, window['Graph'].Widget)
plot_widget = canvas.get_tk_widget()
plot_widget.grid(row=0, column=0)

theta = 0   # offset angle for each sine curve
while True:

    event, values = window.read(timeout=10)

    if event == sg.WINDOW_CLOSED:
        break

    # Generate points for sine curve.
    x = [degree for degree in range(1080)]
    y = [math.sin((degree+theta)/180*math.pi) for degree in range(1080)]

    # Reset ax
    ax.cla()
    ax.set_title("Sensor Data")
    ax.set_xlabel("X axis")
    ax.set_ylabel("Y axis")
    ax.set_xscale('log')
    ax.grid()

    plt.plot(x, y)      # Plot new curve
    fig.canvas.draw()   # Draw curve really

    theta = (theta + 10) % 360  # change offset angle for curve shift on Graph

window.close()

你可以发现这里只调用了一次 FigureCanvasTkAgg 或类似你的 FigureCanvasTkAgg 的东西,这里没有调用 delete_figure_agg,只是调用了 ax.cla() 来清除数字。