Search code examples
pythonpython-3.xmatplotlibkinematicsinverse-kinematics

How do I animate a rotating link in matplotlib plot?


I will keep the problem simple.

Let's say I have a link of length 15 units and I want to make it animate in the matplotlib plot as the value of theta(angle between the link and x axis) varies from 0 to 90 degrees. The link should rotate about the (0,0) coordinates, i.e. the link is fixed at the (0,0) coordinates.

Obviously trigonometry rules will be applied to find the coordinates of the other end of the link while one end is fixed at (0,0) coordinates.

I just want to use purely matplotlib and numpy modules.


Solution

  • As you might know already, matplotlib provides built-in support for animations. The FuncAnimation class is the simplest interface for native matplotlib animations.

    %matplotlib widget
    from matplotlib import pyplot as plt
    from matplotlib.animation import FuncAnimation, PillowWriter
    import numpy as np
    
    fig = plt.figure()
    ax = plt.subplot(111, projection='polar')
    
    class LinkAnimator:
        # Also check this example from the official documentation for this pattern:
        # https://matplotlib.org/3.3.3/gallery/animation/bayes_update.html
    
        def __init__(self, ax, link_size=15):
            self._ax = ax
            self._link_size = link_size
            self._link = self._ax.plot([0, 0], [0, 15], lw=1.5)[0]
            
        def __call__(self, theta):
            self._link.set_data([theta] * 2, [0, 15])
            return self._link
        
    animator = LinkAnimator(ax, link_size=15)
    theta = np.linspace(0, np.pi / 2, 91)
    anim = FuncAnimation(fig, animator, frames=theta, blit=True, repeat=False)
    
    # if you want to export the animation as a gif
    writer = PillowWriter(fps=25)
    anim.save('/tmp/link-anim.gif', writer=writer)
    
    # this shall display your animation in the notebook
    plt.show()
    

    I have taken the liberty of using polar coordinates. If you are not familiar with this, do check this example from the official documentation.

    USER GUIDE: https://matplotlib.org/3.3.3/api/animation_api.html#funcanimation

    Here's what the above code generates: Here's what the above code generates