'graph no actualizing on pysimplegui with matplotlib

I have the following code, I want my GUI to change my two graphs everytime I press the button, but only the one in the left changes. Can someone please help me.

It's very strange because I took care of saving all the canvas and that way I can edit them with first using .forget() but for some reason it really doesn't work for the first graph.

import PySimpleGUI as sg
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# VARS CONSTS:

# New figure and plot variables so we can manipulate them

_VARS = {'window': False,
         'fig_agg1': False,
         'pltFig1': False,
        'fig_agg2': False,
         'pltFig2': False}

dataSize = 1000  # For synthetic data

# Helper Functions


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 update_graph(zoom,or1,or2):
    updateChart(1,zoom,or1,or2)
    updateChart(2,zoom,or1,or2)

# \\  -------- PYSIMPLEGUI -------- //

AppFont = 'Any 16'
sg.theme('DarkTeal12')

#layout = [[sg.Canvas(key='figCanvas')],
#          [sg.Button('Update', font=AppFont), sg.Button('Exit', font=AppFont)]]

control_col=sg.Column([
    [sg.Frame('Zoom',layout = [[sg.Slider(range = (0,100), orientation = 'h', key = '-ZOOM-')]])],
    [sg.Frame('Orientation 1',layout = [[sg.Slider(range = (-180,180), orientation = 'h', key = '-OR1-')]])],
    [sg.Frame('Orientation 2',layout = [[sg.Slider(range = (-180,180), orientation = 'h', key = '-OR2-')]])],
    [sg.Checkbox('Blackhole 1' , key = '-BH1-')],
    [sg.Checkbox('Blackhole 2' , key = '-BH2-')],
    [sg.Checkbox('Blackhole 3' , key = '-BH3-')],
    [sg.Button('Show', key = '-SHOW-')]
    
])

graph1_col=sg.Column([[sg.Canvas(key = '-CANVAS1-')]])
graph2_col=sg.Column([[sg.Canvas(key = '-CANVAS2-')]])

layout=[[control_col,graph1_col,graph2_col]]

#_VARS['window'] = sg.Window('Such Window',
#                            layout,
#                            finalize=True,
#                            resizable=True,
#                            location=(100, 100),
#                            element_justification="right")

_VARS['window'] =  sg.Window('Visualization', layout, finalize = True)

# \\  -------- PYSIMPLEGUI -------- //


# \\  -------- PYPLOT -------- //


def makeSynthData():
    xData = np.random.randint(100, size=dataSize)
    yData = np.random.randint(100, size=dataSize)
    zData = np.random.randint(100, size=dataSize)
    return (xData, yData, zData)


def drawChart(number):
    _VARS['pltFig'+str(number)] = plt.figure()
    dataXYZ = makeSynthData()
    #plt.plot(dataXYZ[0], dataXYZ[1],dataXYZ[2] '.k')
    ax = plt.axes(projection='3d')
    ax.scatter3D(dataXYZ[0], dataXYZ[1], dataXYZ[2], c=dataXYZ[2], cmap='Greens')
    _VARS['fig_agg'+str(number)] = draw_figure(
        _VARS['window']['-CANVAS'+str(number)+'-'].TKCanvas, _VARS['pltFig'+str(number)])


# Recreate Synthetic data, clear existing figre and redraw plot.

def updateChart(number,zoom,or1,or2):
    _VARS['fig_agg'+str(number)].get_tk_widget().forget()
    dataXYZ = makeSynthData()
    # plt.cla()
    plt.clf()
    #plt.plot(dataXYZ[0], dataXYZ[1], '.k')
    ax = plt.axes(projection='3d')
    ax.scatter3D(dataXYZ[0], dataXYZ[1], dataXYZ[2], c=dataXYZ[2], cmap='Greens')
    ax.view_init(or1, or2)
    _VARS['fig_agg'+str(number)] = draw_figure(
        _VARS['window']['-CANVAS'+str(number)+'-'].TKCanvas, _VARS['pltFig'+str(number)])

# \\  -------- PYPLOT -------- //


drawChart(1)
drawChart(2)

# MAIN LOOP

while True:
    event, values = _VARS['window'].read(timeout = 50)
    
    if event == sg.WIN_CLOSED:
        break
    if event == '-SHOW-':
        print(values)
        update_graph( 
                 values['-ZOOM-'],
                 values['-OR1-'],
                 values['-OR2-'])
        
        
_VARS['window'].close()



Solution 1:[1]

For plt.figure

  • Option num: A unique identifier for the figure.
  • If a figure with that identifier already exists, this figure is made active and returned.

Following code set which figure activated to draw

def drawChart(number):
    _VARS['pltFig'+str(number)] = plt.figure()

After

drawChart(1)
drawChart(2)

Active figure set to figure 2 and not been changed until script end.

Try to update following statement in your code.

def drawChart(number):
    _VARS['pltFig'+str(number)] = plt.figure(num=number)
def updateChart(number,zoom,or1,or2):
    _VARS['fig_agg'+str(number)].get_tk_widget().forget()
    dataXYZ = makeSynthData()
    plt.figure(num=number)

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jason Yang