2012-12-06 56 views
0

我有多個繪製在Matplotlib中的同一軸上的繪製線。我試圖使用滑塊控件來調整線路,但由於某些原因只有第一線圖顯示時,當我移動滑塊沒有被更新:在同一軸上使用Matplotlib滑塊和多個繪圖

import matplotlib.pyplot as p 
from matplotlib.widgets import Slider, Button, RadioButtons 

Kd=0.0 
Ks=0.0 
mass=0.02 

width=900 
yPosition = [] 
yVelocity = [] 
yTarget = [] 
yForce = [] 
lpos= [] 
lvel = [] 
ltarget = [] 
lforce = [] 

def runSimulation(positionGain=1.5, velocityGain=60.0): 
    global Kd, Ks, mass, yPosition, yVelocity, yTarget, yForce, width 

    velocity = 0.0 
    acceleration = 0.0 
    reference = 100.0 
    target = 0.0 
    position = 0.0 
    force = 0.0 
    T=0.0005 

    yPosition = [] 
    yVelocity = [] 
    yTarget = [] 
    yForce = [] 

    for i in range(0,width*10): 
     acceleration = (force - Kd*velocity - Ks*position)/mass 

     # Equations of motion for constant acceleration 
     position = position + (velocity*T) + (0.5*acceleration*T*T) 
     velocity = velocity + acceleration*T 

     e1 = target - position # Output of 1st control system 
     e2 = positionGain * e1 - velocity # Output of 2nd control system 
     force = velocityGain * e2 

     if i % 10 == 0: #Plot 1 point for every 10 iterations of simulation 
      if i>=30: 
       target = reference 
      else: 
       target = 0 
      yPosition.append(position) 
      yVelocity.append(velocity*0.1) 
      yTarget.append(target) 
      yForce.append(force*0.001) 

def plotGraph(): 
    global yPosition, yVelocity, yTarget, yForce, lpos, lvel, ltarget, lforce 
    x = range(0,width) 
    ax = p.subplot(111) 
    lpos, = ax.plot(x,yPosition,'r') 
    lvel, = ax.plot(x,yVelocity,'g') 
    ltarget, = ax.plot(x,yTarget,'k') 
    lforce, = ax.plot(x,yForce,'b') 

ax = p.subplot(111) 
p.subplots_adjust(left=0.25, bottom=0.25) 
runSimulation() 
plotGraph() 

p.axis([0, 1, -10, 10]) 

axcolor = 'lightgoldenrodyellow' 
axpos = p.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) 
axvel = p.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) 

spos = Slider(axpos, 'Position Gain', 1.0, 20.0, valinit=1.5) 
svel = Slider(axvel, 'Velocity Gain', 5.0, 500.0, valinit=60.0) 

def update(val): 
    global yPosition,yVelocity,yTarget,yForce 
    runSimulation(round(spos.val,2),round(svel.val,2)) 
    lpos.set_ydata(yPosition) 
    lvel.set_ydata(yVelocity) 
    ltarget.set_ydata(yTarget) 
    lforce.set_ydata(yForce) 
    p.draw() 

spos.on_changed(update) 
svel.on_changed(update) 
p.show() 

如果刪除plotGraph()之間的界限和p.show()你可以看到原始的情節。

回答

3

說實話,你對軸定位和更新功能有些混亂。我冒昧地再次寫策劃部分,擺在那裏評論:

# run your simulation like usual 
runSimulation() 

#create a ordered grid of axes, not one in top of the others 
axcolor = 'lightgoldenrodyellow' 
fig = p.figure() 
axdata = p.subplot2grid((7,4),(0,0),colspan=4,rowspan=4) 
axpos = p.subplot2grid((7,4),(-2,0),colspan=4, axisbg=axcolor) 
axvel = p.subplot2grid((7,4),(-1,0),colspan=4, axisbg=axcolor) 

# create your plots in the global space. 
# you are going to reference these lines, so you need to make them visible 
# to the update functione, instead of creating them inside a function 
# (and thus losing them at the end of the function) 
x = range(width) 
lpos, = axdata.plot(x,yPosition,'r') 
lvel, = axdata.plot(x,yVelocity,'g') 
ltarget, = axdata.plot(x,yTarget,'k') 
lforce, = axdata.plot(x,yForce,'b') 

# same as usual 
spos = Slider(axpos, 'Position Gain', 1.0, 20.0, valinit=1.5) 
svel = Slider(axvel, 'Velocity Gain', 5.0, 500.0, valinit=60.0) 


def update(val): 
    # you don't need to declare the variables global, as if you don't 
    # assign a value to them python will recognize them as global 
    # without problem 
    runSimulation(round(spos.val,2),round(svel.val,2)) 
    lpos.set_ydata(yPosition) 
    lvel.set_ydata(yVelocity) 
    ltarget.set_ydata(yTarget) 
    lforce.set_ydata(yForce) 
    # you need to update only the canvas of the figure 
    fig.canvas.draw() 

spos.on_changed(update) 
svel.on_changed(update) 
p.show() 

順便說一句,如果你要模擬一個阻尼振盪,我強烈建議你給看看到的集成模塊scipy,其中包含odeint函數以比你在做什麼更好的方式積分微分方程(這稱爲歐拉積分,並且真是容易出錯)

+0

非常好 - 謝謝!我只是擴展了Matplotlib文檔(http://matplotlib.org/examples/widgets/slider_demo.html)中的slider_demo.py示例,但使用subplot2grid的方法更爲清晰。 – Gerrit

相關問題