2016-09-22 3 views
1

대화식 matplotlib 위젯을 사용하여 미분 방정식의 솔루션을 시각화했습니다. 나는 scipy에서 odeint 함수로 작업하고 있지만 ode 클래스로 업데이트 할 수는 없습니다. 후자는 솔버가 사용되는 것을보다 잘 제어하므로 오히려 후자를 사용하려고합니다.대화 형 matplotlib 위젯이 scipy ode 해석기로 업데이트되지 않음

다음 코드는 기하 급수적 인 차이를 해결하는 데 사용됩니다. y0는 감쇠의 진폭입니다. solver.integrate (t1)가 update 함수 내에서 호출되면 코드가 작동을 멈 춥니 다. 왜 이런지 모르겠습니다.

from scipy.integrate import ode 

# solve the system dy/dt = f(t, y) 
def f(t, y): 
    return -y/10 

# Array to save results to 
def solout(t, y): 
    sol.append([t, *y]) 
solver = ode(f).set_integrator('dopri5') 
solver.set_solout(solout) 

# Initial conditions 
y0 = [1] # Initial amplitude 
t0 = 0  # Start time 
t1 = 20 # End time 

fig = plt.figure(figsize=(10, 6)) 
fig.subplots_adjust(left=0.25, bottom=0.4) 
ax = plt.subplot(111) 

# solve the DEs 
solver.set_initial_value(y0, t0) 
sol = [] 
solver.integrate(t1) 
sol = np.array(sol) 
t = sol[:, 0] 
y = sol[:, 1] 

l, = plt.plot(t, y, lw=2, color='red') 
plt.axis([0, 20, 0, 1.1]) 
plt.xlabel('Time (ms)') 
plt.ylabel('n1(t)') 
plt.grid() 

axcolor = 'lightgoldenrodyellow' 
axn1 = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) 
sn1 = Slider(axn1, 'y(0)', 0, 1.0, valinit=1) 
def update(val): 
    y0 = [sn1.val] 
    solver.set_initial_value(y0, t0) 
    sol = [] 
    solver.integrate(t1) 
    sol = np.array(sol) 
    t = sol[:, 0] 
    y = sol[:, 1] 
    l.set_data(t, y) 
    plt.draw() 
sn1.on_changed(update) 

답변

0

필자는 계산을 플로팅과 분리하는 것이 현명하다고 생각합니다. 따라서 먼저 주어진 초기 조건으로 ODE를 해결하십시오. 일단 작동하면 음모를 꾸미고 대화식으로 작업 해보십시오.

우리는 ODE를 해결하는 함수를 작성한 다음 플로팅 업데이트에서도 다른 초기 조건으로이 함수를 사용합니다.

import matplotlib.pyplot as plt 
from matplotlib.widgets import Slider 
import numpy as np 
from scipy.integrate import ode 


# solve the system dy/dt = f(t, y) 
def f(t, y): 
    a = np.zeros((1,1)) 
    a[0] = -y/10. 
    return a 

#define a function to solve the ODE with initial conditions 
def solve(t0, t1, y0, steps=210): 
    solver.set_initial_value([y0], t0) 
    dt = (t1 - t0)/(steps - 1) 
    solver.set_initial_value([y0], t0) 
    t = np.zeros((steps, 1)) 
    Y = np.zeros((steps, 1)) 
    t[0] = t0 
    Y[0] = y0 
    k = 1 
    while solver.successful() and k < steps: 
     solver.integrate(solver.t + dt) 
     t[k] = solver.t 
     Y[k] = solver.y[0] 
     k += 1 
    return t, Y 

# set the ODE integrator 
solver = ode(f).set_integrator("dopri5") 
# Initial conditions 
y0 = 1. # Initial amplitude 
t0 = 0.  # Start time 
t1 = 20. # End time 
#solve once for given initial amplitude 
t, Y = solve(t0, t1, y0) 


fig = plt.figure(figsize=(10, 6)) 
fig.subplots_adjust(left=0.25, bottom=0.4) 
ax = plt.subplot(111) 

l, = plt.plot(t, Y, lw=2, color='red') 
plt.axis([0, 20, 0, 1.1]) 
plt.xlabel('Time (ms)') 
plt.ylabel('n1(t)') 
plt.grid() 

axn1 = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg='#e4e4e4') 
sn1 = Slider(axn1, 'y(0)', 0, 1.0, valinit=1) 
def update(val): 
    #solve again each time 
    t, Y = solve(t0, t1, sn1.val) 
    l.set_data(t, Y) 
    plt.draw() 
sn1.on_changed(update) 

plt.show() 
+0

정말 고맙습니다. 내가 어떻게 그 수입 함수를 놓쳤는 지 모르겠다 ... 내 코드가 작동하지 않는 이유는 sol과 solout의 가변 범위 문제 때문이라고 생각한다. 나는 당신의 코드를 적응 시켜서 솔 아웃으로 작업하게함으로써 적응 가능한 스텝 크기를 가질 수있게했다. 다시 한 번 감사드립니다. –

관련 문제