Skip to content

Instantly share code, notes, and snippets.

@ninux
Last active November 25, 2023 22:28
Show Gist options
  • Save ninux/98f4c962efe251df0deaf94fdbdb7699 to your computer and use it in GitHub Desktop.
Save ninux/98f4c962efe251df0deaf94fdbdb7699 to your computer and use it in GitHub Desktop.
python tkinter sine plotter GUI
import threading
import time
import tkinter as tk
from tkinter import messagebox
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
NavigationToolbar2Tk)
from matplotlib import animation
from matplotlib import style
class SINEPLOTTERGUI:
def __init__(self):
self.root = tk.Tk()
#style.use("dark_background")
# attributes
self.amplitude = 1
self.frequency = 1
self.time = 1
self.timestep = 0.001
# initial geometry
self.root.geometry("900x500")
# menubar
self.menubar = tk.Menu(self.root)
# close menu
self.closemenu = tk.Menu(self.menubar, tearoff=0)
self.closemenu.add_command(label="Close", command=self.on_closing)
self.menubar.add_cascade(menu=self.closemenu, label="File")
# about menu
self.aboutmenu = tk.Menu(self.menubar, tearoff=0)
self.aboutmenu.add_command(label="About", command=self.show_about)
self.menubar.add_cascade(menu=self.aboutmenu, label="About")
self.root.config(menu=self.menubar)
# plot figure
self.frame = tk.Frame(self.root)
self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)
self.frame.grid(row=0, column=0, rowspan=10, columnspan=1, sticky="nsew")
self.canvas.get_tk_widget().pack()
# program name label
self.name_label_frame = tk.Frame(self.root)
self.name_label = tk.Label(self.name_label_frame, text="Sine Plotter", font=('Arial', 12))
self.name_label_frame.grid(row=0, column=1, columnspan=2, sticky="nsew")
self.name_label.pack(fill=tk.BOTH)
# plot button
self.plot_button_frame = tk.Frame(self.root)
self.plot_button = tk.Button(self.plot_button_frame, text="plot", font=('Arial', 10), command=self.plot)
self.plot_button_frame.grid(row=1, column=1, columnspan=2, sticky="nsew")
self.plot_button.pack(fill=tk.BOTH)
# frequency label
self.frequency_label_frame = tk.Frame(self.root)
self.frequency_label = tk.Label(self.frequency_label_frame, text="Frequency (Hz)")
self.frequency_label_frame.grid(row=2, column=1, sticky="nsw")
self.frequency_label.pack(fill=tk.BOTH)
# frequency slider
self.frequency_slider_frame = tk.Frame(self.root)
self.frequency_slider = tk.Scale(self.frequency_slider_frame, from_=1, to=10, orient=tk.HORIZONTAL, command=self.set_frequency)
self.frequency_slider.set(self.get_frequency())
self.frequency_slider_frame.grid(row=2, column=2, sticky="nsew")
self.frequency_slider.pack(fill=tk.BOTH)
# amplitude label
self.amplitude_label_frame = tk.Frame(self.root)
self.amplitude_label = tk.Label(self.amplitude_label_frame, text="Amplitude (V)")
self.amplitude_label_frame.grid(row=3, column=1, sticky="nsw")
self.amplitude_label.pack(fill=tk.BOTH)
# amplitude slider
self.amplitude_slider_frame = tk.Frame(self.root)
self.amplitude_slider = tk.Scale(self.amplitude_slider_frame, from_=1, to=10, orient=tk.HORIZONTAL, command=self.set_amplitude)
self.amplitude_slider.set(self.get_amplitude())
self.amplitude_slider_frame.grid(row=3, column=2, sticky="nsew")
self.amplitude_slider.pack(fill=tk.BOTH)
# time label
self.time_label_frame = tk.Frame(self.root)
self.time_label = tk.Label(self.time_label_frame, text="Time (s)")
self.time_label_frame.grid(row=4, column=1, sticky="nsw")
self.time_label.pack(fill=tk.BOTH)
# time slider
self.time_slider_frame = tk.Frame(self.root)
self.time_slider = tk.Scale(self.time_slider_frame, from_=1, to=10, orient=tk.HORIZONTAL, command=self.set_time)
self.time_slider.set(self.get_time())
self.time_slider_frame.grid(row=4, column=2, sticky="nsew")
self.time_slider.pack(fill=tk.BOTH)
# timestep label
self.timestep_label_frame = tk.Frame(self.root)
self.timestep_label = tk.Label(self.timestep_label_frame, text="Timestep (ms)")
self.timestep_label_frame.grid(row=5, column=1, sticky="nsw")
self.timestep_label.pack(fill=tk.BOTH)
# timestep slider
self.timestep_slider_frame = tk.Frame(self.root)
self.timestep_slider = tk.Scale(self.timestep_slider_frame, from_=1, to=1000, orient=tk.HORIZONTAL, command=self.set_timestep)
self.timestep_slider_frame.grid(row=5, column=2, sticky="nsew")
self.timestep_slider.pack(fill=tk.BOTH)
# function selection label
self.funsel_label_frame = tk.Frame(self.root)
self.funsel_label = tk.Label(self.funsel_label_frame, text="Function")
self.funsel_label_frame.grid(row=6, column=1, sticky="nsw")
self.funsel_label.pack(fill=tk.BOTH)
# function selection radio
self.funsel_value = tk.StringVar(self.root, "1")
self.funsel_options = {
"sine" : "1",
"cosine" : "2"
}
self.funsel_radio_frame = tk.Frame(self.root)
self.funsel_radio = []
for (txt, val) in self.funsel_options.items():
self.funsel_radio.append(tk.Radiobutton(self.funsel_radio_frame, text=txt, variable=self.funsel_value, value=val, anchor="w"))
self.funsel_radio_frame.grid(row=6, column=2, sticky="snew")
for q in range(len(self.funsel_radio)):
self.funsel_radio[q].pack(fill=tk.BOTH)
col_count, row_count = self.root.grid_size()
for col in range(col_count):
self.root.grid_columnconfigure(col, minsize=0)
for row in range(row_count):
self.root.grid_rowconfigure(row, minsize=0)
#self.root.mainloop()
def on_closing(self):
if messagebox.askyesno(title="Quit?", message="Do you really want to quit?"):
self.root.destroy()
def show_about(self):
messagebox.showinfo(title="About", message="Sine Plotter, Version 0.0")
def get_frequency(self):
return self.frequency
def get_amplitude(self):
return self.amplitude
def get_time(self):
return self.time
def get_timestep(self):
return self.timestep
def set_frequency(self, value):
self.frequency = int(value)
return self.frequency
def set_amplitude(self, value):
self.amplitude = int(value)
return self.amplitude
def set_time(self, value):
self.time = int(value)
return self.time
def set_timestep(self, value):
self.timestep = int(value) * 1e-3
return self.timestep
def plot(self):
self.ax.clear()
function = self.funsel_value.get()
t = np.arange(0, self.get_time(), self.timestep, dtype=float)
y = t * 0
if function == self.funsel_options["sine"]:
y = self.get_amplitude() * np.sin(2 * np.pi * self.get_frequency() * t)
elif function == self.funsel_options["cosine"]:
y = self.get_amplitude() * np.cos(2 * np.pi * self.get_frequency() * t)
self.ax.plot(t, y)
self.ax.set_xlabel("Time (s)")
self.ax.set_ylabel("Voltage (V)")
self.ax.grid(visible=False)
self.canvas.draw()
spg = SINEPLOTTERGUI()
tk.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment