Created
January 20, 2019 18:18
-
-
Save MikeTheWatchGuy/9eccd789e5880b614a159324af239c6e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
if sys.version_info[0] >= 3: | |
import PySimpleGUI as sg | |
else: | |
import PySimpleGUI27 as sg | |
from random import randint | |
import PySimpleGUI as sg | |
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg | |
from matplotlib.figure import Figure | |
import matplotlib.backends.tkagg as tkagg | |
import tkinter as tk | |
import random, math | |
import matplotlib.pyplot as plt | |
import matplotlib.animation as animation | |
import matplotlib.gridspec as gridspec | |
class MakeFig: | |
def __init__(self): | |
self.numOfPoints = 1 # How many current G-force points do we want? | |
self.theta = .4 # controls resolution of outer bound points, smaller theta = more points | |
# random starter values for global stuff | |
self.ActTheta = 0.0 | |
self.ActRadius = 0.0 | |
self.points = [] | |
self.outerPoints = [] | |
self.barlist = [] | |
self.maxOverallG = .1 | |
self.maxSectorG = .1 | |
self.currentMaxG = .1 | |
self.fig = plt.figure() | |
self.gs = gridspec.GridSpec(2, 1, height_ratios=[4, 1]) | |
self.ax1 = self.fig.add_subplot(self.gs[0], projection='polar') | |
self.ax2 = self.fig.add_subplot(self.gs[1]) | |
self.initBounds() | |
self.initGPoints() | |
self.initBars() | |
def outerGridCreate(self): | |
radius = .5 | |
p1 = (radius, 0) | |
thetaWorking = 0 | |
while thetaWorking < 2 * math.pi: | |
self.outerPoints.append(p1) | |
thetaWorking = round((thetaWorking + self.theta), 6) | |
p1 = (thetaWorking, radius) | |
self.outerPoints.pop(0) # remove last entry for drawing reasons. | |
def randomPoint(self): | |
RThet = random.randint(-9, 9) / 20 | |
RRad = random.randint(-9, 9) / 20 | |
self.ActTheta = self.ActTheta + RThet | |
self.ActRadius = self.ActRadius + RRad | |
if self.ActRadius < 0: | |
self.ActRadius = abs(self.ActRadius) | |
if self.ActRadius > 1.8: | |
self.ActRadius = 0 + RRad | |
if self.ActTheta < 0: | |
self.ActTheta = (2 * math.pi) + self.ActTheta | |
if self.ActTheta > 2 * math.pi: | |
self.ActTheta = 0 + RThet | |
self.ActTheta = round(self.ActTheta, 6) | |
self.ActRadius = round(self.ActRadius, 6) | |
self.checkOuterBounds(self.ActTheta, self.ActRadius) | |
return (self.ActTheta, self.ActRadius) | |
def checkOuterBounds(self, pTheta, pRad): | |
DistFromCenter = pRad | |
self.currentMaxG = DistFromCenter | |
if self.currentMaxG == 0: | |
self.currentMaxG = .1 | |
if DistFromCenter < .5: # we don't need to check these points, so don't bother | |
return self.maxOverallG, self.maxSectorG, self.currentMaxG | |
# Use theta to figure out what sector we're in | |
nearPoint1 = [p for p in self.outerPoints if (p[0] >= pTheta) and (p[0] <= (pTheta + self.theta))] | |
nearPoint2 = [x for x in self.outerPoints if (x[0] < pTheta) and (x[0] > (pTheta - self.theta))] | |
# If we didn't find anything, it's becuase we're at the zero line sector, so push 'em | |
if nearPoint1 == []: | |
nearPoint1 = [self.outerPoints[0]] | |
if nearPoint2 == []: | |
nearPoint2 = [self.outerPoints[-1]] | |
nearPoint1 = nearPoint1[0] | |
nearPoint2 = nearPoint2[0] | |
# Figure out if we need to push the sector boundaries out | |
if DistFromCenter > nearPoint1[1]: | |
nnp1 = (nearPoint1[0], DistFromCenter) | |
self.outerPoints[:] = [nnp1 if (p[0] == nearPoint1[0] and p[1] == nearPoint1[1]) else p for p in self.outerPoints] | |
if DistFromCenter > nearPoint2[1]: | |
nnp2 = (nearPoint2[0], DistFromCenter) | |
self.outerPoints[:] = [nnp2 if (p[0] == nearPoint2[0] and p[1] == nearPoint2[1]) else p for p in self.outerPoints] | |
if nearPoint1[1] > nearPoint2[1]: | |
self.maxSectorG = nearPoint1[1] | |
else: | |
self.maxSectorG = nearPoint2[1] | |
if self.maxSectorG > self.maxOverallG: | |
self.maxOverallG = self.maxSectorG | |
self.ax2.axes.set_xlim(0, self.maxOverallG) | |
def animateGPoints(self, i): # animates the actual blue G point reading | |
global numOfPoints | |
self.points.append(self.randomPoint()) | |
N = self.numOfPoints | |
while len(self.points) > self.numOfPoints: | |
self.points.pop(0) | |
theta_val = [x[0] for x in self.points] | |
rad_val = [x[1] for x in self.points] | |
ln = self.ax1.plot(theta_val[-N:], rad_val[-N:], 'bo-') | |
return ln | |
def animateBounds(self, i): # animate the outer yellow bound points | |
self.ax1.cla() | |
self.ax1.set_ylim(0, 2) | |
self.ax1.axes.set_yticklabels([]) | |
self.ax1.axes.set_xticklabels([]) | |
theta_val = [t[0] for t in self.outerPoints] | |
rad_val = [r[1] for r in self.outerPoints] | |
theta_val.append(theta_val[0]) | |
rad_val.append(rad_val[0]) | |
out = self.ax1.plot(theta_val, rad_val, 'y-') | |
return out | |
def animateBars(self, i): # animate the lower limit bars | |
Nums = [self.maxOverallG, self.maxSectorG, self.currentMaxG] | |
self.ax2.axes.set_ylim(0, 1) | |
self.ax2.axes.tick_params(left=False, bottom=False) | |
self.ax2.axes.set_yticklabels([]) | |
for i in enumerate(barlist): | |
i[1][0].set_width(Nums[i[0]]) | |
thing2 = self.ax2.plot() | |
self.fig.canvas.draw() | |
return thing2 | |
def initGPoints(self): | |
points = [] | |
c = 0 | |
while c <= self.numOfPoints: # create initial list of 10 points | |
points.append(self.randomPoint()) | |
c = c + 1 | |
ox_val = [x[0] for x in points] # split it so we can plot it | |
oy_val = [x[1] for x in points] | |
ln = self.ax1.plot(points[0], points[1]) | |
return ln | |
def initBounds(self): # generate the initial outside grip circle points | |
self.outerGridCreate() | |
theta_val = [t[0] for t in self.outerPoints] | |
rad_val = [r[1] for r in self.outerPoints] | |
out = self.ax1.plot(theta_val, rad_val) | |
return out | |
def initBars(self): | |
global barlist | |
max_G = 1.0 | |
current_sec = .4 | |
current = .3 | |
p1 = self.ax2.barh(0, max_G, height=2, color='gray') | |
p2 = self.ax2.barh(0, current_sec, height=2, color='red') | |
p3 = self.ax2.barh(0, current, height=2, color='green') | |
barlist = [p1, p2, p3] | |
return barlist | |
def main(): | |
# define the form layout | |
layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')], | |
[sg.Canvas(size=(640, 480), key='canvas')], | |
[sg.ReadButton('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 | |
mfig = MakeFig() | |
i = 0 | |
while True: | |
event, values = window.Read(timeout=10) | |
if event is 'Exit' or event is None: | |
exit(69) | |
# fig = make_fig() | |
fig = mfig.fig | |
mfig.animateBars(i) | |
mfig.animateBounds(i) | |
mfig.animateGPoints(i) | |
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() | |
# Unfortunately, there's no accessor for the pointer to the native renderer | |
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2) | |
i += 1 | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment