使用python Matplotlib制作沿半圆的线动画

j0pj023g  于 2022-11-15  发布在  Python
关注(0)|答案(1)|浏览(174)

正如标题所说,我正在尝试制作一个节拍器动画,但是,我不确定从这一点上做什么。现在,我已经成功地制作了一个从固定点上下移动的棍子动画,但是,我遇到的问题是使棍子在半圆内前后移动(就像节拍器一样)。以下是我目前为止的代码

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
import matplotlib

i = 80

matplotlib.use('TkAgg')

fig = matplotlib.figure.Figure(figsize=(5, 4), dpi=100)
fig.add_subplot(111).plot(1,4)

points = (1, 5, 10, 10, 5, 1)

fig, ax = plt.subplots()
xfixdata, yfixdata = 10, 5
xdata, ydata = 5, 10
ln, = plt.plot([], [], 'ro-', animated=True)
plt.plot([xfixdata], [yfixdata], 'bo', ms=10)

def init():
    ax.set_xlim(0, 20)
    ax.set_ylim(0, 20)
    return ln,

def update(frame):
    # ydata = points[frame]
    ydata = np.sin(1 + (1 + 2*frame))
    ln.set_data([xfixdata,xdata], [yfixdata,ydata])
    return ln,

ani = FuncAnimation(fig, update, interval=i, init_func=init, blit=True)
plt.axis('on')

def draw_figure(canvas, figure):
    figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
    figure_canvas_agg.draw()
    figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas_agg

#Gui Code

# define the window layout
layout = [[sg.Text('UI Test')],
          [sg.Canvas(key='-CANVAS-')],
          [sg.Button('Speed Up'), sg.Button('Slow Down')],
          [sg.Text(i)],
          [sg.Button('Exit')]
          ]

# create the form and show it without the plot
window = sg.Window('UI Test For Conductor Robot', layout, finalize=True,
                   element_justification='center', font='Helvetica 18')

# add the plot to the window
fig_canvas_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)

event, values = window.read()

while True:
    event, values = window.read()

    if event == "Exit" or event == sg.WIN_CLOSED:
        break
    if event == "Speed Up":
        i = i + 10

window.close()

另外,我遇到的另一个问题是制作一个按钮来提高动画的速度。正如您在代码中所看到的,我创建了一个I值来存储值80。然后,我将间隔设置为I,并制作了一个按钮,当按下该按钮时,该按钮会将I值增加10,因此,减慢了动画的速度。它不起作用。如果你能帮助这将是很好的,但是,我目前关心的主要问题是制作节拍器的动画。谢谢你的阅读!

db2dz4w8

db2dz4w81#

对于此处使用的PySimpleGUI,不需要库Matplotlib
示例代码这里只是演示动画,bpm是不正确或准确的,也没有声音在这里。

import math
import time
import threading
import PySimpleGUI as sg

def func(window):
    global running
    while running:
        time.sleep(0.031)
        window.write_event_value('Update', None)
    window.write_event_value('Done', None)

h, pad, range1, range2 = 160, 20, 40, 200
size = ((h+pad)*2, h+pad)
bpm, step = 60, -4
max_angle = 3000/bpm
angle = 90 + max_angle

sg.theme('Dark')
layout = [
    [sg.Graph(size, (-h-pad, 0), (h+pad, h+pad), background_color='green', key='-GRAPH-')],
    [sg.Slider((range1, range2), default_value=bpm, resolution=4, tick_interval=16, orientation='h', enable_events=True, expand_x=True, key='-Slider-')]
]
window = sg.Window('Metronome', layout, margins=(0, 0), finalize=True, enable_close_attempted_event=True)

graph = window['-GRAPH-']
pointer = graph.draw_line((0, -pad), (h*math.cos(angle/180*math.pi), h*math.sin(angle/180*math.pi)), color='white', width=5)
running = True
thread = threading.Thread(target=func, args=(window,), daemon=True)
thread.start()

while True:

    event, values = window.read()

    if event == sg.WIN_CLOSE_ATTEMPTED_EVENT:
        running = False
    elif event == 'Update':
        graph.delete_figure(pointer)
        angle += step
        if step < 0 and angle <= 90 - max_angle:
            angle = 90 - max_angle
            step = -step
        elif step > 0 and angle >= 90 + max_angle:
            angle = 90 + max_angle
            step = -step
        pointer = graph.draw_line((0, -pad), (h*math.cos(angle/180*math.pi), h*math.sin(angle/180*math.pi)), color='white', width=5)
    elif event == '-Slider-':
        bpm = values[event]
        max_angle = 3000//bpm
    elif event == 'Done':
        break

window.close()

相关问题