Updated to work with 3.1.1

This commit is contained in:
PySimpleGUI 2019-09-19 11:24:40 -04:00
parent 0248d6e968
commit ec78bd3327
1 changed files with 33 additions and 61 deletions

View File

@ -1,16 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
import matplotlib import matplotlib
matplotlib.use('TkAgg') matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasAgg
import matplotlib.backends.tkagg as tkagg
import tkinter as Tk
import inspect import inspect
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
""" """
Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window. Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
@ -20,10 +15,10 @@ Basic steps are:
* Display form (NON BLOCKING) * Display form (NON BLOCKING)
* Draw plots onto convas * Draw plots onto convas
* Display form (BLOCKING) * Display form (BLOCKING)
Each plotting function, complete with imports, was copied directly from Matplot examples page
""" """
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@ -825,39 +820,24 @@ def AxesGrid():
plt.draw() plt.draw()
return plt.gcf() return plt.gcf()
# The magic function that makes it possible.... glues together tkinter and pyplot using Canvas Widget # The magic function that makes it possible.... glues together tkinter and pyplot using Canvas Widget
def draw_figure(canvas, figure, loc=(0, 0)): def draw_figure(canvas, figure, loc=(0, 0)):
""" Draw a matplotlib figure onto a Tk canvas figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
loc: location of top-left corner of figure on canvas in pixels.
Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
"""
figure_canvas_agg = FigureCanvasAgg(figure)
figure_canvas_agg.draw() figure_canvas_agg.draw()
figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
figure_w, figure_h = int(figure_w), int(figure_h) return figure_canvas_agg
photo = Tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
# Position: convert from top-left anchor to center anchor
canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)
# Unfortunately, there's no accessor for the pointer to the native renderer
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
# Return a handle which contains a reference to the photo object
# which must be kept live or else the picture disappears
return photo
def delete_figure_agg(figure_agg):
figure_agg.get_tk_widget().forget()
plt.close('all')
# -------------------------------- GUI Starts Here -------------------------------# # -------------------------------- GUI Starts Here -------------------------------#
# fig = your figure you want to display. Assumption is that 'fig' holds the # # fig = your figure you want to display. Assumption is that 'fig' holds the #
# information to display. # # information to display. #
# --------------------------------------------------------------------------------# # --------------------------------------------------------------------------------#
# print(inspect.getsource(PyplotSimple))
fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'PyPlot Three':Subplot3d, fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'PyPlot Three':Subplot3d,
'Unicode Minus': UnicodeMinus, 'Pyplot Scales' : PyplotScales, 'Axes Grid' : AxesGrid, 'Unicode Minus': UnicodeMinus, 'Pyplot Scales' : PyplotScales, 'Axes Grid' : AxesGrid,
'Exploring Normalizations' : ExploringNormalizations, 'Different Scales' : DifferentScales, 'Exploring Normalizations' : ExploringNormalizations, 'Different Scales' : DifferentScales,
@ -866,41 +846,33 @@ fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'Py
'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots, 'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots,
'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram} 'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram}
sg.ChangeLookAndFeel('LightGreen') sg.ChangeLookAndFeel('LightGreen')
figure_w, figure_h = 650, 650 figure_w, figure_h = 650, 650
# define the form layout # define the form layout
listbox_values = [key for key in fig_dict.keys()] listbox_values = list(fig_dict)
col_listbox = [[sg.Listbox(values=listbox_values, change_submits=True, size=(28, len(listbox_values)), key='func')], col_listbox = [[sg.Listbox(values=listbox_values, change_submits=True, size=(28, len(listbox_values)), key='-LISTBOX-')],
[sg.T(' ' * 12), sg.Exit(size=(5, 2))]] [sg.T(' ' * 12), sg.Exit(size=(5, 2))]]
layout = [[sg.Text('Matplotlib Plot Test', font=('current 18'))], layout = [[sg.Text('Matplotlib Plot Test', font=('current 18'))],
[sg.Column(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='canvas') , [sg.Column(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-') ,
sg.Multiline(size=(70, 35), pad=(5, (3, 90)), key='multiline')],] sg.Multiline(size=(70, 35), pad=(5, (3, 90)), key='-MULTILINE-')],]
# create the form and show it without the plot # create the form and show it without the plot
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', grab_anywhere=False).Layout(layout) window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, grab_anywhere=False, finalize=True)
window.Finalize() figure_agg = None
# The GUI Event Loop
canvas_elem = window.FindElement('canvas')
multiline_elem= window.FindElement('multiline')
while True: while True:
event, values = window.Read() event, values = window.read()
print(event) # print(event, values) # helps greatly when debugging
# show it all again and get buttons if event in (None, 'Exit'): # if user closed window or clicked Exit button
if event in (None, 'Exit'):
break break
if figure_agg:
try: # ** IMPORTANT ** Clean up previous drawing before drawing again
choice = values['func'][0] delete_figure_agg(figure_agg)
func = fig_dict[choice] choice = values['-LISTBOX-'][0] # get first listbox item chosen (returned as a list)
except: func = fig_dict[choice] # get function to call from the dictionary
pass window['-MULTILINE-'].Update(inspect.getsource(func)) # show source code to function in multiline
fig = func() # call function to get the figure
multiline_elem.Update(inspect.getsource(func)) figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig) # draw the figure
plt.clf() window.close()
fig = func()
fig_photo = draw_figure(canvas_elem.TKCanvas, fig)