Making nice animations in python

I wanted to make a simple cos and sine animation in python, and output it as a gif file. Here is the output and the code, hopefully this will be useful as a basis for you to make some cool animations. Let me know what you make in the comments below.

Click here for full size version of this GIF

This version of the code makes an mp4 file provided you have ffmpeg installed on your system. It’s not hard to change it to output images, gif’s and videos of other formats. Check out matplotlib.animation.

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

from matplotlib import rc
rc('text', usetex=True) # Use LaTeX font

import seaborn as sns
sns.set(color_codes=True)


X = np.linspace(0, 4*np.pi, 100)
Y = np.sin(X)
Z = np.cos(X)

#print(X)
#print(Y)
#print(np.info(np.linspace))

xcircoffset = -6
xcirclescale = 3

theta = np.linspace(0, 4*np.pi, 100)
r = np.sqrt(1.0)
x1 = r*np.cos(theta)
x2 = r*np.sin(theta)
x11 = xcirclescale*r*np.cos(theta) + xcircoffset

#Small circle
angle = np.linspace(0, 2*np.pi, 50)
smallr = np.sqrt(0.01)
scx1 = smallr*np.cos(angle)
scx2 = smallr*np.sin(angle)
scx11 = xcirclescale*smallr*np.cos(angle) + xcircoffset


fig, ax = plt.subplots(1,1, figsize=(18,6))
#fig.set_size_inches(50, 50)
ax.set_xlim([0, 4*np.pi])
ax.set_ylim([-1.1, 1.1])
#ax.set_title(r'Test Title')
ax.set_xlabel(r'Angle in Radians')

# X axis labels
ax.set_xticks(np.arange(0,4*np.pi+0.01, np.pi/4))
labels = ['$0$', r'', r'$\frac{\pi}{2}$', r'', r'$\pi$', r'', r'$\frac{3\pi}{2}$', r'', r'$2\pi$', r'', r'$\frac{5\pi}{2}$', r'', r'$3\pi$', r'', r'$\frac{7\pi}{2}$', r'', r'$4\pi$']
ax.set_xticklabels(labels)

# Text examples
#ax.text(3, 0.8, 'boxed italics text in data coords', style='italic', bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
#ax.text(2, -0.5, r'an equation: $E=mc^2$', fontsize=15)

ax.text( -2.75 ,    0 , r'$0\;\;\;2\pi$'    , fontsize=15)
ax.text( -6.1  ,  1.1 , r'$\frac{\pi}{2}$'  , fontsize=15)
ax.text( -9.5  ,    0 , r'$\pi$'            , fontsize=15)
ax.text( -6.1  , -1.2 , r'$\frac{3\pi}{2}$' , fontsize=15)

ax.text( 3.4 , 0.8 , r'$f(x)=sin(x)$' , color='#1f77b4',fontsize=15)
ax.text( 3.4 , 0.7 , r'$f(x)=cos(x)$' , color='#ff7f0e',fontsize=15)


fig.subplots_adjust( left=0.45, right=0.97)

sinegraph, = ax.plot([], [], color='#1f77b4' )
cosgraph,  = ax.plot([], [], color='#ff7f0e' )


#thecirc, = ax.plot([],[], clip_on=False)
thecirc, = ax.plot(x11, x2, color='#DDDDDD',clip_on=False)
crosshairV = ax.plot([0+xcircoffset,0+xcircoffset],[-1,1], clip_on=False, alpha=0.8, color='black', linewidth=0.6, linestyle='dashed')
crosshairH = ax.plot([-1*xcirclescale+xcircoffset, 1*xcirclescale+xcircoffset],[0, 0], clip_on=False, alpha=0.8, color='black', linewidth=0.6, linestyle='dashed')

horizaxis = ax.plot([0, 4*np.pi],[0, 0], clip_on=False, alpha=0.8, color='black', linewidth=0.8, linestyle='dashed')

smallcirc, = ax.plot([], [], color='green',clip_on=False)

dot, = ax.plot([], [], 'o', color='#1f77b4')
anotherdot, = ax.plot([], [], 'o', color='#1f77b4', clip_on=False)
horizontalline, = ax.plot([],[], clip_on=False, alpha=1, color='red', linewidth=0.9, linestyle='dotted')

radiusline, = ax.plot([],[], color='#0000FF', clip_on=False, linewidth = 0.5, alpha=0.5, linestyle='dashed')

vlinecircle, = ax.plot([],[], color='#1f77b4', clip_on=False, linewidth=3.0 ) # represents the sin value
hlinecircle, = ax.plot([],[], color='#ff7f0e', clip_on=False, linewidth=3.0) # represents the cos value

vlinesine, =ax.plot([],[], color='#1f77b4', clip_on=False, linewidth = 3.0)



def sine(i):

    sinegraph.set_data(X[:i],Y[:i])
    cosgraph.set_data(X[:i], Z[:i])
 #   thecirc.set_data( xcirclescale*x1[:i]+xcircoffset, x2[:i]) # This draws the circle in pieces

    #smallcirc, = ax.plot(scx11, scx2, color='green', clip_on=False)
    smallcirc.set_data(scx11[:i%50],scx2[:i%50])

    dot.set_data(X[i],Y[i])
    anotherdot.set_data(x11[i],x2[i])

    horizontalline.set_data([x11[i] ,X[i]],[Y[i],Y[i]])
    radiusline.set_data( [xcircoffset,xcirclescale*x1[i]+xcircoffset]   ,  [  0 ,  Y[i]   ])

    vlinecircle.set_data([xcirclescale*x1[i]+xcircoffset, xcirclescale*x1[i]+xcircoffset ],[0, Y[i] ])
    vlinesine.set_data([X[i] , X[i] ],[0, Y[i]])
    hlinecircle.set_data([xcircoffset, x11[i] ],[0, 0])

anim = animation.FuncAnimation(fig, sine, frames=len(X), interval=120)
#anim.save('./animation.gif', writer='imagemagick', fps=24) #use this to write out as a GIF once happy with it.


writer = animation.writers['ffmpeg']
writer = writer(fps=15)
anim.save('./animation.mp4', writer=writer)

plt.show()

Leave a comment

Your email address will not be published. Required fields are marked *