我有多个线条图,它们绘制在Matplotlib的相同轴上。我正在尝试使用Slider小部件来调整线条,但由于某些原因,只显示第一个线条图,并且在移动滑块时没有更新任何内容:
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()
之间的行,则可以看到原始图。
答案 0 :(得分: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函数,以比你正在做的更好的方式整合微分方程(这就是所谓的欧拉积分,并且确实容易出错)