#!/usr/bin/env python import sys if sys.version_info[0] >= 3: import PySimpleGUI as sg else: import PySimpleGUI27 as sg import matplotlib.pyplot as plt import ping from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg import matplotlib.backends.tkagg as tkagg import tkinter as tk #================================================================================ # Globals # These are needed because callback functions are used. # Need to retain state across calls #================================================================================ class MyGlobals: axis_pings = None ping_x_array = [] ping_y_array = [] g_my_globals = MyGlobals() #================================================================================ # Performs *** PING! *** #================================================================================ def run_a_ping_and_graph(): global g_my_globals # graphs are global so that can be retained across multiple calls to this callback #===================== Do the ping =====================# response = ping.quiet_ping('google.com',timeout=1000) if response[0] == 0: ping_time = 1000 else: ping_time = response[0] #===================== Store current ping in historical array =====================# g_my_globals.ping_x_array.append(len(g_my_globals.ping_x_array)) g_my_globals.ping_y_array.append(ping_time) # ===================== Only graph last 100 items =====================# if len(g_my_globals.ping_x_array) > 100: x_array = g_my_globals.ping_x_array[-100:] y_array = g_my_globals.ping_y_array[-100:] else: x_array = g_my_globals.ping_x_array y_array = g_my_globals.ping_y_array # ===================== Call graphinc functions =====================# g_my_globals.axis_ping.clear() # clear before graphing g_my_globals.axis_ping.plot(x_array,y_array) # graph the ping values #================================================================================ # Function: Set graph titles and Axis labels # Sets the text for the subplots # Have to do this in 2 places... initially when creating and when updating # So, putting into a function so don't have to duplicate code #================================================================================ def set_chart_labels(): global g_my_globals g_my_globals.axis_ping.set_xlabel('Time') g_my_globals.axis_ping.set_ylabel('Ping (ms)') g_my_globals.axis_ping.set_title('Current Ping Duration', fontsize = 12) def draw(fig, canvas): # Magic code that draws the figure onto the Canvas Element's canvas figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds figure_w, figure_h = int(figure_w), int(figure_h) photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h) canvas.create_image(640 / 2, 480 / 2, image=photo) figure_canvas_agg = FigureCanvasAgg(fig) figure_canvas_agg.draw() tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2) return photo #================================================================================ # Function: MAIN #================================================================================ def main(): global g_my_globals # define the form layout layout = [[sg.Text('Animated Ping', size=(40, 1), justification='center', font='Helvetica 20')], [sg.Canvas(size=(640, 480), key='canvas')], [sg.Button('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] # create the form and show it without the plot window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() canvas_elem = window.FindElement('canvas') canvas = canvas_elem.TKCanvas fig = plt.figure() g_my_globals.axis_ping = fig.add_subplot(1,1,1) set_chart_labels() plt.tight_layout() while True: event, values = window.Read(timeout=0) if event in ('Exit', None): break run_a_ping_and_graph() photo = draw(fig, canvas) if __name__ == '__main__': main()