As the name suggests, PySimpleGUI makes it very easy to create a GUI, and you can also create a surprisingly high-performance GUI. I use the PySimple GUI mainly for the purpose of creating research tools, but I often want to embed Matplotlib graphs in the GUI. This article summarizes how to do it. The content of this article is based on the official Cook Book and GitHub.
A random sine wave is drawn each time the Add button is pressed, and it is a simple program that allows you to erase the canvas with the Clear button.
I'm using Python 3.8.2. If it is 3 system, it will work without any problem.
The official documentation describes how to install with pip, but you can also install with Anaconda without any problems. I use Anaconda.
pip install pysimplegui
or
conda install pysimplegui
If you can't install with conda
conda install -c conda-forge pysimplegui
Please try.
I also want to use Matplotlib, so install it.
conda install matplotlib
embedded-matplotlib.py
import numpy as np
import PySimpleGUI as sg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#Functions to prevent GUI blurring
def make_dpi_aware():
import ctypes
import platform
if int(platform.release()) >= 8:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
make_dpi_aware()
#Function for drawing
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
#Layout creation
layout = [[sg.Text('Embed Matplotlib Plot')],
[sg.Canvas(key='-CANVAS-')],
[sg.Button("Add"), sg.Button("Clear")]]
#Create a window. finalize=Must be True.
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True, element_justification='center', font='Monospace 18')
#Create a fig for embedding.
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)
ax.set_ylim(-10, 10)
#Associate fig with Canvas.
fig_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
#Event loop
while True:
event, values = window.read()
print(event, values)
# sg.Print(event, values)
if event in (None, "Cancel"):
break
elif event == "Add":
#Creating appropriate plot data
t = np.linspace(0, 7, 100)
afreq = np.random.randint(1, 10)
amp = np.random.randint(1, 10)
y = amp * np.sin(afreq * t)
#plot
ax.plot(t, y, alpha=0.4)
#After making changes, fig_agg.draw()Reflect the change with.
fig_agg.draw()
elif event == "Clear":
ax.cla()
fig_agg.draw()
#close the window.
window.close()
For the basic part of PySimpleGUI, please refer to the official document.
Although it has nothing to do with the main subject, when the window is displayed with PySimpleGUI, the resolution may become rough and difficult to see. The solution is to run the make_dpi_aware
function at the beginning of the program. Depending on the environment, it seems to be displayed without problems even without this. I always write this process at the beginning of the PySimple GUI program. See This GitHub Issue for more information.
def make_dpi_aware():
import ctypes
import platform
if int(platform.release()) >= 8:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
This is the main subject.
First, create a window. The important thing here is to use Canvas as the element for embedding the plot, and to specify finalize = True
when creating the window.
#Layout creation
layout = [[sg.Text('Embed Matplotlib Plot')],
[sg.Canvas(key='-CANVAS-')],
[sg.Button("Add"), sg.Button("Clear")]]
#Create a window. finalize=Must be True.
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True, element_justification='center', font='Monospace 18')
Next, create the plot you want to embed as usual.
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)
ax.set_ylim(-10, 10)
Next, link the created plot with the Canvas element. You will need the return value of the draw_figure
function later.
#Associate fig with Canvas.
fig_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
The draw_figure
function used here is as follows. Basically, there is no need to change the contents of this function, and you can copy and use it as it is. To use it, you need to import FigureCanvasTkAgg
as shown on the 4th line of the program.
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
Embedding is completed up to this point.
In the created program, pressing the Add button will add a sine wave to the plot. To update the plot in this way, first run ʻax.plot () and then
fig_agg.draw () `to reflect the plot changes.
#Creating appropriate plot data
t = np.linspace(0, 7, 100)
afreq = np.random.randint(1, 10)
amp = np.random.randint(1, 10)
y = amp * np.sin(afreq * t)
#plot
ax.plot(t, y, alpha=0.4)
#After making changes, fig_agg.draw()Reflect the change with.
fig_agg.draw()
Recommended Posts