Синусоидальные волны и плоттер БПФ

Oct 18 2020

Я пытаюсь закодировать синусоидальную волну с помощью 5 ползунков: частота, амплитуда, изменение фазы, количество точек данных и время. В настоящее время я пытаюсь связать свой ползунок изменения фазы с моим графиком, чтобы он обновлял его, когда я перемещаю ползунок. Я понимаю, что мой код, вероятно, довольно беспорядочный и мог бы быть более кратким, но я могу исправить это позже.

Я думаю, что добавление ползунка изменения фазы и времени, на которое строится функция, тоже было бы хорошо, как ползунки частоты и амплитуды (которые действительно работают).

Для тех, кто не знаком с физическими терминами: амплитуда: высота волны (по оси ординат).

  • частота: количество раз, когда волна проходит определенную точку в единицу времени. 1 Герц = 1 волна, проходящая в секунду
  • Разность фаз: изменение начального положения текущей волны, где амплитуда = 0 при t = 0. Изменение фазы на 90 градусов сдвигает функцию влево или вправо, а затем представляет функцию cos, а не синус.

Будем очень признательны за любые советы по моему текущему коду!

Мой код на данный момент:

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()

Ответы

1 RootTwo Oct 20 2020 at 18:20

Мне кажется, вам просто нужно добавить фазу к углу 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