Sinus- und FFT-Plotter

Oct 18 2020

Ich versuche, eine Sinuswelle mit 5 Schiebereglern zu codieren: Frequenz, Amplitude, Phasenänderung, Anzahl der Datenpunkte und Zeit. Ich versuche derzeit, meinen Phasenwechsel-Schieberegler mit meinem Diagramm zu verknüpfen, damit er aktualisiert wird, wenn ich den Schieberegler bewege. Mir ist klar, dass mein Code wahrscheinlich ziemlich chaotisch ist und prägnanter sein könnte, aber ich kann das später anpassen.

Ich denke, das Hinzufügen eines Phasenänderungsreglers und der Zeitdauer, für die die Funktion geplottet wird, wäre ebenfalls gut, wie die Frequenz- und Amplitudenregler (die funktionieren).

Für diejenigen, die mit den physikalischen Begriffen nicht vertraut sind: Amplitude: Höhe der Welle (in y-Achse)

  • Frequenz: Häufigkeit, mit der eine Welle einen bestimmten Punkt pro Zeiteinheit passiert. 1 Hertz = 1 Welle pro Sekunde
  • Phasendifferenz: Die Änderung der Startposition der Stromwelle mit der Amplitude = 0 bei t = 0. Eine 90-Grad-Phasenänderung würde die Funktion nach links oder rechts verschieben und dann eher eine cos-Funktion als einen Sinus darstellen.

Jeder Rat für meinen aktuellen Code wäre sehr dankbar!

Mein Code bisher:

import tkinter
import numpy as np
from scipy import signal
from scipy.fft import fft, ifft as sc
from matplotlib import pyplot as p, animation
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
from matplotlib.widgets import Slider

root = tkinter.Tk()
root.wm_title("Embedding in Tk")
fig = Figure(figsize=(6, 5), dpi=100)
t = np.linspace(0, 5, 200)
f = 1
time = np.linspace(0, 100, 101)
y = np.sin(f*t)

fig.subplots_adjust(left=0.15, bottom=0.45)  # Adjust subplots region leaving room for the sliders 
and buttons

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)


def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)


def _quit():
    root.quit()  # stops mainloop
    root.destroy()


button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)

# Amplitude slider
initiala = 1  # starting value of amplitude on graph
asliderax = fig.add_axes([0.25, 0.15, 0.65, 0.03])  # setting amplitude slider position
aslider = Slider(asliderax, 'Amp', 0.1, 10.0, valinit=initiala)  # setting amplitude slider values

# Frequency slider
initialf = 1  # starting value of frequency on graph
fsliderax = fig.add_axes([0.25, 0.1, 0.65, 0.03])  # setting frequency slider position
fslider = Slider(fsliderax, 'Freq', 0.1, 3.0, valinit=initialf)  # setting frequency slider values

# Time slider
initialt = 1  # starting value of time on graph
tsliderax = fig.add_axes([0.25, 0.2, 0.65, 0.03])  # setting time slider position
tslider = Slider(tsliderax, 'Time', 0.1, 100.0, valinit=initialt)  # setting time slider values

# Number of Points slider
initialp = 99  # starting value of number of points on graph
psliderax = fig.add_axes([0.25, 0.25, 0.65, 0.03])  # setting points slider position
pslider = Slider(psliderax, 'Points', 3, 30.0, valinit=initialp)  # setting frequency points values

# Phase slider
initialph = 0  # starting value of number of points on graph
phsliderax = fig.add_axes([0.25, 0.3, 0.65, 0.03])  # setting points slider position
phslider = Slider(phsliderax, 'Phase Change', 0, np.pi*2, valinit=initialph)  # setting frequency 
points values


def update(val):
    amp = aslider.val
    freq = fslider.val
    t = np.linspace(0, 5, 200)
    y.set_ydata(amp*np.sin(2*np.pi*freq*t))


fslider.on_changed(update)
aslider.on_changed(update)
tslider.on_changed(update)
pslider.on_changed(update)


tkinter.mainloop()

Antworten

1 RootTwo Oct 20 2020 at 18:20

Mir scheint, Sie müssen nur die Phase zum Winkel hinzufügen update().

def update(val):
    amp = aslider.val
    freq = fslider.val
    phase = phslider.val
    t = np.linspace(0, 5, 200)

    y.set_ydata(amp*np.sin(2*np.pi*freq*t + phase))  # << add phase here


fslider.on_changed(update)
aslider.on_changed(update)
tslider.on_changed(update)
pslider.on_changed(update)
phslider.on_changed(update)  # update on slider change