简体   繁体   English

Pysimple GUI 不清除 matplotlib 图形画布

[英]Pysimple GUI not clearing matplotlib graph canvas

Context: Posted a similar q before and now I have to use radio buttons instead of a list of functions.上下文:之前发布过类似的 q,现在我必须使用单选按钮而不是功能列表。 The reason is that when I input my file for processing, the input variables for the graphs will be defined at this point and not earlier in the code, so the only way to do this is to use radio buttons so I can add the function input params here.原因是当我输入我的文件进行处理时,图形的输入变量将在此时定义,而不是在代码的前面,所以唯一的方法是使用单选按钮,这样我就可以添加函数输入参数在这里。

Issue: My issue is that when I click the radio button, the previous graph is not cleared, and the new graph prints below the original one.问题:我的问题是,当我单击单选按钮时,上一个图形未清除,新图形打印在原始图形下方。 Please could someone help out - thank you!请有人帮忙 - 谢谢!

Minimum code example here:这里的最小代码示例:

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()

Before you draw new figure or axes, you may need method cla() or clf() to clear your figure.在绘制新图形或轴之前,您可能需要方法cla()clf()来清除图形。 Find them in Matplotlib.在 Matplotlib 中找到它们。

It is not necessary to do following imports in function PyplotSimple and PyplotSimple2 .没有必要在函数PyplotSimplePyplotSimple2执行以下导入。

    import numpy as np
    import matplotlib.pyplot as plt

Here, you create the figure_agg again after you delete it.在这里,您在删除后再次创建figure_agg Remove comment-marked line.删除注释标记的行。

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

Actually实际上

  • One more canvas added on your PSG canvas when draw_figure called调用 draw_figure 时,在 PSG 画布上又添加了一张画布
  • Not delete canvas when delete_figure_agg called, just forgot it in pack调用 delete_figure_agg 时不删除画布,只是在包中忘记了它

Here's another example show how I work matplotlib figure on PSG canvas.这是另一个示例,展示了我如何在 PSG 画布上处理 matplotlib 图。

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()

You can find just call once to FigureCanvasTkAgg or something like your FigureCanvasTkAgg here, and no delete_figure_agg called here, but just ax.cla() called to clear figure.你可以找到只调用一次FigureCanvasTkAgg或类似你的FigureCanvasTkAgg在这里,这里没有调用delete_figure_agg ,但只ax.cla()来清除图形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM