Search code examples
pythonmatplotlibtrigonometrymatplotlib-animation

Matplotlib animation of a step


I creating a Matplotlib animation of a step function. I am using the following code...

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))

line, = ax.step([], [])

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

def animate(i):
    x = np.linspace(0, 2, 10)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

plt.show()

It vaguely resembles what I desire (something like the gif below) but instead of the values being constant and scrolling with time each step is dynamic and shifts up and down. How would go about changing my code to achieve this shift?

enter image description here


Solution

  • step explicitly plots steps between the input data points. It can never plot a partial "step".

    You're wanting an animation with "partial steps" in between.

    Instead of using ax.step, use ax.plot, but make a stepped series by plotting y = y - y % step_size.

    In other words, something like:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.linspace(0, 10, 1000) # Using a series of 1000 points...
    y = np.sin(x)
    
    # Make *y* increment in steps of 0.3
    y -= y % 0.3
    
    fig, ax = plt.subplots()
    ax.plot(x, y)
    plt.show()
    

    Notice the partial "steps" at the beginning and end enter image description here

    Incorporating this into your animation example, we'd get something similar to:

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib import animation
    
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
    
    line, = ax.plot([], [])
    
    def init():
        line.set_data([], [])
        return line,
    
    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        y -= y % 0.3
        line.set_data(x, y)
        return line,
    
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=100, interval=20, blit=True)
    
    plt.show()
    

    enter image description here