Inspired by https://dribbble.com/shots/1696376-Circle-wave
They are several ways to produce such a plot :
I tried the second approach here
In [ ]:
%matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as manimation
plt.ion()
In [ ]:
nwave = 8
amp_wave = 0.1
rad_wave = 0.8
frames = 100
npoints=500
In [ ]:
# We want a square figure with a black background
fig = plt.figure(facecolor='k', figsize=(5,5))
# Obviously a polar plot and enough space to see all the curves
ax = fig.add_subplot(111, polar=True)
ax.set_xlim(0,rad_wave+amp_wave*1.1)
ax.set_ylim(0,rad_wave+amp_wave*1.1)
# Let's put everything in black and remove the axis
ax.set_axis_bgcolor('black')
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
for spine in ax.spines.itervalues():
spine.set_visible(False)
We basically need two cosine plots
In [ ]:
x = np.linspace(0,2*np.pi,npoints)
plots = [ ax.plot(x, rad_wave+amp_wave*np.cos(nwave*x), color='w', linewidth=4)[0], \
ax.plot(x, rad_wave-amp_wave*np.cos(nwave*x), color='w', linewidth=4)[0] ]
fig.tight_layout()
We can define an atenuation filter on those plots, let's try a simple gaussian
In [ ]:
tau = np.exp(-(x-np.pi)**2/(2*(np.pi/4)**2))
plots[0].set_ydata(rad_wave+amp_wave*np.cos(nwave*x)*tau)
plots[1].set_ydata(rad_wave-amp_wave*np.cos(nwave*x)*tau)
Looks good enough, we can try to animate it by shifting the filter
In [ ]:
def init():
return plots
def update_image(iframe):
global x
tau = np.roll( np.exp(-(x-np.pi)**2/(2*(np.pi/4)**2)), -int(iframe*1.0/frames*npoints))
plots[0].set_ydata( rad_wave+amp_wave*np.cos(nwave*x)*tau )
plots[1].set_ydata( rad_wave-amp_wave*np.cos(nwave*x)*tau )
return plots
In [ ]:
map_animation = manimation.FuncAnimation(fig, update_image, init_func=init, frames=frames, interval=50, repeat=True)
plt.show()
And we can simply save this animation as a gif
In [ ]:
map_animation.save('circle-wave.gif', writer='imagemagic', dpi=40, fps=25, savefig_kwargs=dict(facecolor=fig.get_facecolor(), edgecolor='none'))
And if everything worked properly you should get a tidy gif :