Skip to content

Instantly share code, notes, and snippets.

@JoeRicotta
Created September 15, 2023 16:05
Show Gist options
  • Select an option

  • Save JoeRicotta/e3bf4ef3e0620d987670307242a0c0bf to your computer and use it in GitHub Desktop.

Select an option

Save JoeRicotta/e3bf4ef3e0620d987670307242a0c0bf to your computer and use it in GitHub Desktop.
synergy index simulation
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import matplotlib.image as mpimg
from matplotlib.patches import Rectangle
import numpy as np
from pprint import pp
vucm_init = 2.5
vort_init = 2.5
class Synergy(object):
def __init__(self, vucm, vort, _n=10):
self._vucm = vucm
self._vort = vort
self._dv = (vucm-vort)/(vucm+vort)
self._vtot = vucm + vort
self.ucm = np.array([1/np.sqrt(2), -1/np.sqrt(2)])
self.ort = np.array([1/np.sqrt(2),1/np.sqrt(2)])
self._onb = np.array((self.ucm,self.ort))
self._sigma = np.array([[vucm, 0],[0,vort]])
self._cov = self._onb.T @ self._sigma @ self._onb
self.sample = np.random.multivariate_normal([5,5], self._cov, _n)
self._scale()
self._show_ucm = True
self._show_ort = True
self._show_data = False
@property
def vucm(self):
return self._vucm
@vucm.setter
def vucm(self, value):
self._scale(vucm=value)
self._vucm = value
@property
def vort(self):
return self._vort
@vort.setter
def vort(self,value):
self._scale(vort=value)
self._vort = value
@property
def dv(self):
return (self._vucm - self._vort) / (self._vucm + self._vort)
def _scale(self,vucm=None,vort=None):
if vucm is None:
vucm = self._vucm
if vort is None:
vort = self._vort
sample_mean = self.sample.mean(0)
sample = self.sample - sample_mean
# scaling cofficients
scale_mat = np.array([[np.sqrt(vucm/self._vucm),0],
[0,np.sqrt(vort/self._vort)]])
new_sample = (sample @ self._onb.T @ scale_mat @ self._onb) + np.array([5,5])
self.sample = new_sample
# setting sample features
syn = Synergy(vucm_init,vort_init,_n=20)
# getting all ready
root = tkinter.Tk()
root.wm_title("Embedding in Tk")
# creating figure
ax_tog = ["-","None"]
alpha_tog = [0,1]
fig = Figure(figsize=(10, 10), dpi=100)
ax = fig.subplots(1,1)
ax.set_xlim((0,12))
ax.set_ylim((0,12))
ax.set_title(f"Synergy index simulation")
ax.set_xlabel("F2 (N)")
ax.set_ylabel("F1 (N)")
scat = ax.scatter(syn.sample[:,0], syn.sample[:,1])
text = ax.text(x=5,y=10,s=f"$\Delta V$={round(syn.dv,4)}",size=20)
text.set_alpha(0)
scat.set_alpha(0)
ucm_line = ax.axline(xy1=[10,0],xy2=[0,10], c="black", label = "UCM")
ucm_line.set_linestyle("None")
ort_line = ax.axline(xy1=[0,0],slope=1, c="red", alpha=.4, label = "ORT")
ort_line.set_linestyle("None")
ax.legend()
# drawing canvas
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
# pack_toolbar=False will make it easier to use a layout manager later on.
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()
canvas.mpl_connect(
"key_press_event", lambda event: print(f"you pressed {event.key}"))
canvas.mpl_connect("key_press_event", key_press_handler)
def toggle_data():
syn._show_data = not syn._show_data
scat.set_alpha(alpha_tog[syn._show_data])
text.set_alpha(alpha_tog[syn._show_data])
canvas.draw()
def toggle_ucm():
syn._show_ucm = not syn._show_ucm
ucm_line.set_linestyle(ax_tog[syn._show_ucm])
ax.legend()
canvas.draw()
def toggle_ort():
syn._show_ort = not syn._show_ort
ort_line.set_linestyle(ax_tog[syn._show_ort])
ax.legend()
canvas.draw()
def update_vucm(new_val):
f = float(new_val)/1000
syn.vucm = f
# update image plot of weight
scat.set_offsets(offsets=syn.sample)
text.set_text(f"$\Delta V$={round(syn.dv,4)}")
# required to update canvas and attached toolbar!
canvas.draw()
def update_vort(new_val):
f = float(new_val)/1000
syn.vort = f
# update image plot of weight
scat.set_offsets(offsets=syn.sample)
text.set_text(f"$\Delta V$={round(syn.dv,4)}")
# required to update canvas and attached toolbar!
canvas.draw()
# buttons
button_data = tkinter.Button(master=root, text="data", command=toggle_data)
button_ucm = tkinter.Button(master=root, text="ucm", command=toggle_ucm)
button_ort = tkinter.Button(master=root, text="ort", command=toggle_ort)
button_quit = tkinter.Button(master=root, text="Quit", command=root.destroy)
# threshold slider
vucm_slider = tkinter.Scale(root, from_=1, to=5000, tickinterval=0.01, orient=tkinter.HORIZONTAL, command=update_vucm, label="Vucm")
vort_slider = tkinter.Scale(root, from_=1, to=5000, tickinterval=0.01, orient=tkinter.HORIZONTAL, command=update_vort, label="Vort")
vucm_slider.set(syn.vucm*1000)
vort_slider.set(syn.vort*1000)
# Packing order is important. Widgets are processed sequentially and if there
# is no space left, because the window is too small, they are not displayed.
# The canvas is rather flexible in its size, so we pack it last which makes
# sure the UI controls are displayed as long as possible.
button_data.pack(side=tkinter.BOTTOM)
button_ucm.pack(side=tkinter.BOTTOM)
button_ort.pack(side=tkinter.BOTTOM)
button_quit.pack(side=tkinter.BOTTOM)
vucm_slider.pack(side=tkinter.BOTTOM)
vort_slider.pack(side=tkinter.BOTTOM)
toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=True)
tkinter.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment