Благодаря @ImportanceOfBeingErnest мне удалось объединить update
функцию анимации и функцию с ползунками:
import numpy as np
%matplotlib notebook
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Slider
fig = plt.figure(figsize=(6,7))
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, position=[.15,.15,.75,.75] )
ax.grid()
w = 2
r = 1
fps = 36
M= 1024#
T_final = 256
x_e, y_e = [], []
orb_x, orb_y = [], []
# trajectories
traj_e, = ax.plot(x_e,y_e,'-g',lw=1)
# center
e, = ax.plot([], [], 'ok')
# orbit
orb, = ax.plot([], [], '.r',ms=1)
# time
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
def positions(t):
x = r*np.cos(w*t) # epicycle
y = r*np.sin(w*t) # epicycle
return x,y
def orbit(r):
phi = np.linspace(0, 2*np.pi, 360)
orb_x = r*np.cos(phi)
orb_y = r*np.sin(phi)
return orb_x,orb_y
def init():
ax.plot([0], ms=7, c='k',marker='o')
return e,traj_e
def update(t):
global r, w
w = s_w.val
r = s_r.val
ax.set_xlim(-(r)*1.1, (r)*1.1)
ax.set_ylim(-(r)*1.1, (r)*1.1)
x,y = positions(t)
x_e.append(x)
y_e.append(y)
traj_e.set_data(x_e[-M:-1], y_e[-M:-1])
orb.set_data(orbit(r))
e.set_data(x, y)
time_text.set_text('time = %.1f' % t)
return traj_e,e, orb
ax_w = plt.axes([0.1, 0.05, 0.35, 0.03])#, facecolor=axcolor)
ax_r = plt.axes([0.55, 0.05, 0.35, 0.03])#, facecolor=axcolor)
s_w = Slider(ax_w, r'$\omega$', -20, 20, valinit=w, valstep=0.2)
s_r = Slider(ax_r, r'r', 0, 5, valinit=r, valstep=0.2)
s_w.on_changed(update)
s_r.on_changed(update)
def anim():
fig.canvas.draw_idle()
return FuncAnimation(fig, update, frames=np.linspace(0, T_final, T_final*fps),
init_func=init, blit=True, interval=30)
anim()
Используя этот фрагмент кода, я могу изменить значения r
и w
без остановки или перезапуска анимации с нуля. Однако с этим кодом возникает еще одна проблема, заключающаяся в том, что точка переходит в некоторую случайную позицию на окружности, а затем переходит обратно на ожидаемую траекторию. Я бы сказал об этом в другом вопросе.