使用Matplotlib滑块在同一轴上具有多个打印

2024-09-28 17:20:50 发布

您现在位置:Python中文网/ 问答频道 /正文

在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()之间的线,则可以看到原始的绘图。在


Tags: targetpositionaxwidthforcevelocityypositionacceleration
1条回答
网友
1楼 · 发布于 2024-09-28 17:20:50

老实说,您在轴定位和更新函数上搞得有点乱。我冒昧地把密谋的部分写了一遍,并在里面写了评论:

# 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函数,可以用比你现在做的更好的方法来积分微分方程(这叫做Euler积分,很容易出错)

相关问题 更多 >