0

I am trying to plot a ball bouncing on a vertically oscillating surface. I think the code (relating to the variables) is working however the figures are not updating to reflect the variables changing thanks to the loops. I hope it's not to vague a question but why are they not updating?

Thanks!

import numpy as np
import matplotlib.pyplot as plt


    h_b=np.array([10])#initial ball height
    g=-9.8 #gravity acceleration
    #v_b=np.array([0]) 
    v_b=np.array([0.0001])#initial ball velocity
    dt=0.1 #time-step

    a=3 #amplitude of surface's movement
    f=0.2 #frequency of the oscillations
    h_s=np.array([0]) #height of the oscillating surface 
    v_s=np.array([a*2*np.pi*f]) #velocity of the oscillating surface

    r=0.9 #coefficient of restitution

    x=np.linspace(0,20,20)

    t=np.array([0]) # setting up the time array


    fig= plt.figure()
    ax1=fig.add_subplot(1,2,1)
    ax2=fig.add_subplot(1,2,2)
    while np.abs(h_b[-1])>0.00001 and np.abs(v_b[-1])>0.00001 :
        while h_b[-1]>h_s[-1] :
            n=len(v_b)
            ax1.clear()
            ax1.set_xlim(0,20)
            ax1.set_ylim(-a,50)
            ax1.plot(10,h_b[n-1],'.',x,np.ones(20)*h_s[n-1])
            ax2.clear()
            ax2.plot(t,h_b)
            plt.show()
            v_b=np.append(v_b,v_b[n-1]+g*dt)
            h_b=np.append(h_b,h_b[n-1]+v_b[n-1]*dt)
            h_s=np.append(h_s,a*np.sin(2*np.pi*f*n*dt))
            v_s=np.append(v_s,a*2*np.pi*f*np.cos(2*np.pi*f*n*dt))
            t=np.append(t,n*dt)
            plt.pause(0.1)
        v_b[-1]=v_s[-2]-r*(v_b[-2]-v_s[-2])
        print('%f' % v_b[-1])
        h_b[-1]=h_s[-1]+0.0001
Tom Weisner
  • 13
  • 1
  • 4
  • You want this to update in real-time, like a video or an animation you can watch rather than plotting the trajectory of the ball over time (in a static plot) - is that correct? – combinatorist Oct 14 '17 at 16:31
  • You may want to refer to these questions: https://stackoverflow.com/questions/11874767/real-time-plotting-in-while-loop-with-matplotlib, https://stackoverflow.com/questions/10944621/dynamically-updating-plot-in-matplotlib – combinatorist Oct 14 '17 at 16:33
  • @combinatorist Yep that's correct. What the other answerer said worked though so all is good. Thanks! – Tom Weisner Oct 14 '17 at 18:43

1 Answers1

0

You should not call plt.show in the loop. It is meant to be called only once at the end of the script. If you remove plt.show(), it'll work as expected.

import numpy as np
import matplotlib.pyplot as plt

plt.ion()
h_b=np.array([10])#initial ball height
g=-9.8 #gravity acceleration
#v_b=np.array([0]) 
v_b=np.array([0.0001])#initial ball velocity
dt=0.1 #time-step

a=3 #amplitude of surface's movement
f=0.2 #frequency of the oscillations
h_s=np.array([0]) #height of the oscillating surface 
v_s=np.array([a*2*np.pi*f]) #velocity of the oscillating surface

r=0.9 #coefficient of restitution

x=np.linspace(0,20,20)

t=np.array([0]) # setting up the time array


fig= plt.figure()
ax1=fig.add_subplot(1,2,1)
ax2=fig.add_subplot(1,2,2)
plt.draw()

while np.abs(h_b[-1])>0.00001 and np.abs(v_b[-1])>0.00001 :

    while h_b[-1]>h_s[-1] :
        n=len(v_b)
        ax1.clear()
        ax1.set_xlim(0,20)
        ax1.set_ylim(-a,50)
        ax1.plot(10,h_b[n-1],'.',x,np.ones(20)*h_s[n-1])
        ax2.clear()
        ax2.plot(t,h_b)

        v_b=np.append(v_b,v_b[n-1]+g*dt)
        h_b=np.append(h_b,h_b[n-1]+v_b[n-1]*dt)
        h_s=np.append(h_s,a*np.sin(2*np.pi*f*n*dt))
        v_s=np.append(v_s,a*2*np.pi*f*np.cos(2*np.pi*f*n*dt))
        t=np.append(t,n*dt)
        plt.pause(0.1)
    v_b[-1]=v_s[-2]-r*(v_b[-2]-v_s[-2])
    print('%f' % v_b[-1])
    h_b[-1]=h_s[-1]+0.0001

plt.ioff()
plt.show()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712