2016-05-22 13 views
1

私は、揺れのシステムをシミュレートするために、thisビットのPythonコードを使っていました。私は方程式を少し変更し、それはうまくプロットします。しかし、私はまた、this gifのような後に永続的なトレースを追加したいと思います。ここでPython matplotlibオブジェクトのパスをアニメ化する

は(あなたはODEがプロットされたデータを生成する解い必要があるので、私はこれ以上それをトリミングすることはできません)私の完全なコードで、該当ビットが終わり近くにある:

import numpy as np 
from scipy.integrate import odeint 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
from numpy import sin, cos, pi, array 

spring_constant = 22.93 
length = 0.16 
mass = 0.1 

# initial conditions 
init = array([-0.35, 0, 0.08, 1]) # initial values 
     #array([theta, theta_dot, x, x_dot]) 

#Return derivatives of the array z (= [theta, theta_dot, x, x_dot]) 
def deriv(z, t, spring_k, spring_l, bob_mass): 
    k = spring_k 
    l = spring_l 
    m = bob_mass 
    g = 9.8 

    theta = z[0] 
    thetadot = z[1] 
    x = z[2] 
    xdot= z[3] 

    return array([ 
     thetadot, 
     (-1.0/(l+x)) * (2*xdot*thetadot + g*sin(theta)), 
     xdot, 
     g*cos(theta) + (l+x)*thetadot**2 - (k/m)*x 
     ]) 

#Create time steps 
time = np.linspace(0.0,10.0,1000) 

#Numerically solve ODE 
y = odeint(deriv,init,time, args = (spring_constant, length, mass)) 

l = length 
r = l+y[:,2] 
theta = y[:,0] 
dt = np.mean(np.diff(time)) 

x = r*sin(theta) 
y = -r*cos(theta) 

##MATPLOTLIB BEGINS HERE## 

fig = plt.figure() 
ax = fig.add_subplot(111, autoscale_on=False, 
        xlim=(-1.2*r.max(), 1.2*r.max()), 
        ylim=(-1.2*r.max(), 0.2*r.max()), aspect = 1.0) 
ax.grid() 

##ANIMATION STUFF BEGINS HERE## 

line, = ax.plot([], [], 'o-', lw=2) 
time_template = 'time = %.1fs' 
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) 

def init(): 
    line.set_data([], []) 
    time_text.set_text('') 
    return line, time_text 


def animate(i): 
    thisx = [0, x[i]] 
    thisy = [0, y[i]] 

    line.set_data(thisx, thisy) 

    time_text.set_text(time_template%(i*dt)) 
    return line, time_text 

ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), 
    interval=25, blit=True, init_func=init) 

plt.show() 

私が作ってみましたたびにアニメーションループの呼び出しを追加して、これまでの各フレームを、それらの点のすべてを描きます点のリスト:

time_template = 'time = %.1fs' 
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) 
foox = [] 
fooy = [] 

def init(): 
    line.set_data([], []) 
    foo.set_data([], []) 
    time_text.set_text('') 
    return line, time_text, foo 


def animate(i): 
    thisx = [0, x[i]] 
    thisy = [0, y[i]] 

    foox += [x[i]] 
    fooy += [y[i]] 

    line.set_data(thisx, thisy) 
    foo.set_data(foox, fooy) 

    time_text.set_text(time_template%(i*dt)) 
    return line, time_text, foo 

しかし、私は

UnboundLocalError: local variable 'foox' referenced before assignment 
を取得

これは、グローバル変数を使用するときに好きではないと思いますか? animate()スコープの外で変数を使用せずにどのポイントを描画したかの履歴を保持する方法がわかりません。誰でも知っている?

ありがとうございます。

EDIT

私はそれを解決しました。私は誤って.append()の代わりに+ =を使用していました。今私は馬鹿のように感じる。

後世のために、それは次のようになります。

def animate(i): 
    thisx = [0, x[i]] 
    thisy = [0, y[i]] 

    foox.append(x[i]) 
    fooy.append(y[i]) 

    line.set_data(thisx, thisy) 
    foo.set_data(foox, fooy) 

    time_text.set_text(time_template%(i*dt)) 
    return line, time_text, foo 

答えて

0

あなたはglobal

foolineとしてそれらを宣言せずに、あなたのアニメーション機能でグローバル変数を変更しているにも冗長

それ以外

あり、あなたのアニメーションはうまくいく。あなたはそれを見るために、次のコードを実行することができます。

import numpy as np 
from scipy.integrate import odeint 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
from numpy import sin, cos, pi, array 

spring_constant = 22.93 
length = 0.16 
mass = 0.1 

# initial conditions 
init = array([-0.35, 0, 0.08, 1]) # initial values 
     #array([theta, theta_dot, x, x_dot]) 

#Return derivatives of the array z (= [theta, theta_dot, x, x_dot]) 
def deriv(z, t, spring_k, spring_l, bob_mass): 
    k = spring_k 
    l = spring_l 
    m = bob_mass 
    g = 9.8 

    theta = z[0] 
    thetadot = z[1] 
    x = z[2] 
    xdot= z[3] 

    return array([ 
     thetadot, 
     (-1.0/(l+x)) * (2*xdot*thetadot + g*sin(theta)), 
     xdot, 
     g*cos(theta) + (l+x)*thetadot**2 - (k/m)*x 
     ]) 

#Create time steps 
time = np.linspace(0.0,10.0,1000) 

#Numerically solve ODE 
y = odeint(deriv,init,time, args = (spring_constant, length, mass)) 

l = length 
r = l+y[:,2] 
theta = y[:,0] 
dt = np.mean(np.diff(time)) 

x = r*sin(theta) 
y = -r*cos(theta) 

##MATPLOTLIB BEGINS HERE## 

fig = plt.figure() 
ax = fig.add_subplot(111, autoscale_on=False, 
        xlim=(-1.2*r.max(), 1.2*r.max()), 
        ylim=(-1.2*r.max(), 0.2*r.max()), aspect = 1.0) 
ax.grid() 

##ANIMATION STUFF BEGINS HERE## 

line, = ax.plot([], [], 'o-', lw=2) 

time_template = 'time = %.1fs' 
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) 
foox = [] 
fooy = [] 
#foo.set_data(foox, fooy) 

def init(): 
    global line, time_text, foo 
    line.set_data([], []) 
# foo.set_data([], []) 
    time_text.set_text('') 
    return line, time_text#, foo 


def animate(i): 
    global foox, fooy, foo 
    thisx = [0, x[i]] 
    thisy = [0, y[i]] 

    foox += [x[i]] 
    fooy += [y[i]] 

    line.set_data(thisx, thisy) 
# foo.set_data(foox, fooy) 

    time_text.set_text(time_template%(i*dt)) 
    return line, time_text#, foo 

ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), interval=25, blit=False, init_func=init) 

plt.show() 

最後の私がチェックしたので、私はblit=Falseを設定して、blitは、私はそれを解決しOSX

+0

おかげで、私はそれが+ = APPENDに変更することで、作業だけれども。これらの違いは何ですか?また、なぜグローバル変数の宣言が必要なのでしょうか? – dain

+0

リストは、「格納された」オブジェクトへのポインタ/参照を格納する変更可能なオブジェクトである。 –

+1

blitはOSXバックエンドでしか動作しません。他のインタラクティブバックエンド( '* agg'で終わるもの)を使用すると動作します。 – tacaswell

0

に取り組んでいませんでした。私は誤って.append()の代わりに+ =を使用していました。今私は馬鹿のように感じる。

は、後世のために、それは次のようになります。

def animate(i): 
    thisx = [0, x[i]] 
    thisy = [0, y[i]] 

    foox.append(x[i]) 
    fooy.append(y[i]) 

    line.set_data(thisx, thisy) 
    foo.set_data(foox, fooy) 

    time_text.set_text(time_template%(i*dt)) 
    return line, time_text, foo 
関連する問題