I am trying to make a simple interactive plot, where a value of single variable can be changed by the slider. I already have non-interactive code which is working, where I use pandas DataFrame. I am using PySimpleGUI, to which I am completely new. I have managed to get a window with the slider, but no plot which changes. Where do I do an error in my code?
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import copy as copy
import PySimpleGUI as sg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
V_A=5
dfN_A=np.array([[-1, 1], [0, 3], [1, -1]])
dfN=copy.deepcopy(dfN_A)
dfN[:,-1]=dfN_A[:,-1]*V_A
DC = pd.DataFrame(dfN,
columns=['X','value'])
_VARS = {'window': False,
'fig_agg': False,
'pltFig': False,
'V_A': 5}
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
AppFont = 'Any 16'
SliderFont = 'Any 14'
sg.theme('black')
layout = [[sg.Canvas(key='figCanvas', background_color='#FDF6E3')],
# pad ((left, right), (top, bottom))
[sg.Text(text="V_A :",
font=SliderFont,
background_color='#FDF6E3',
pad=((0, 0), (10, 0)),
text_color='Black'),
sg.Slider(range=(-10,10), size=(60, 10),
orientation='h', key='-SLIDERV_A-')],
[sg.Button('Exit', font=AppFont, pad=((540, 0), (0, 0)))]]
_VARS['window'] = sg.Window('Simple GUI', layout, finalize=True,resizable=True, element_justification='center', font='Helvetica 18')
def drawChart():
_VARS['pltFig'] = plt.figure()
fig = plt.gcf()
DC.plot(y='value',x='X')
_VARS['fig_agg'] = draw_figure(
_VARS['window']['figCanvas'].TKCanvas, _VARS['pltFig'])
def updateChart():
_VARS['fig_agg'].get_tk_widget().forget()
plt.cla()
plt.clf()
_VARS['fig_agg'] = draw_figure(
_VARS['window']['figCanvas'].TKCanvas, _VARS['pltFig'])
def updateDataV_A(val):
_VARS['V_A'] = val
updateChart()
drawChart()
while True:
event, values = _VARS['window'].read(timeout=2000)
if event == sg.WIN_CLOSED or event == 'Exit':
break
elif event == '-SliderV_A-':
updateDataV_A(int(values['-SliderV_A-']))
_VARS['window'].close()
CodePudding user response:
There're some issues in your code. Try not to say much about those issues, for easily, so a different code here for you.
import numpy as np
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
# 1. Define the class as the interface between matplotlib and PySimpleGUI
class Canvas(FigureCanvasTkAgg):
"""
Create a canvas for matplotlib pyplot under tkinter/PySimpleGUI canvas
"""
def __init__(self, figure=None, master=None):
super().__init__(figure=figure, master=master)
self.canvas = self.get_tk_widget()
self.canvas.pack(side='top', fill='both', expand=1)
# 2. Define a function to draw the figure
def plot_figure(var):
ax.cla()
ax.plot(x0, y0*var)
canvas.draw() # Rendor figure into canvas
# 3. Initial Values
var = 5
x0, y0 = np.array([-1, 0, 1]), np.array([1, 3, -1])
# 4. create PySimpleGUI window
sg.theme('DarkBlue3')
layout = [
[sg.Canvas(size=(640, 480), key='Canvas')],
[sg.Text(text="Var"),
sg.Slider(range=(-10, 10), default_value=var, size=(10, 20), expand_x=True, enable_events=True, orientation='h', key='Slider')],
[sg.Push(), sg.Button('Exit'), sg.Push()],
]
window = sg.Window('Simple GUI', layout, finalize=True, resizable=True)
# 5. Create a matplotlib canvas under sg.Canvas or sg.Graph
fig = Figure()
ax = fig.add_subplot()
canvas = Canvas(fig, window['Canvas'].Widget)
# 6. initial for figure
plot_figure(var)
# 7. PySimpleGUI event loop
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif event == 'Slider':
var = values[event]
plot_figure(var)
# 8. Close window to exit
window.close()