## Section19.6Spherical Harmonics

The spherical harmonics

\begin{equation*} Y_\ell{}^m(\theta,\phi) = N e^{im\phi} P_\ell{}^m(\cos\theta) \end{equation*}

with $$\ell$$ a nonnegative integer and $$m$$ an integer satisfying $$|m|\le\ell$$ are solutions of the partial differential equation

\begin{equation*} r^2 \nabla^2 Y_\ell{}^m = -\ell(\ell+1) Y_\ell{}^m \end{equation*}

where $$P_\ell{}^m$$ is an associated Legendre polynomial, and $$\nabla^2$$ is the Laplacian on the sphere, that is

\begin{equation*} \nabla^2 f = \frac{1}{\sin\theta}\frac{\partial}{\partial\theta} \left(\sin\theta\Partial{f}{\theta}\right) + \frac{1}{r^2\sin^2\theta}\frac{\partial^2 f}{\partial\phi^2} \end{equation*}

and $$N$$ is a normalization factor.

You can print the first few spherical harmonics using the following Sage code.

pretty_print_default(True)
theta,phi=var('theta,phi')
@interact
def _(l=(0,5,1)):
@interact
def _(m=slider(-l,l,step_size=1,default=0)):
spherical_harmonic(l,m,theta,phi).show()


You can also explore the graphs of the spherical harmonics using Sage. The code below plots the squared magnitude (probability density) $$|Y_\ell{}^m|^2$$ of the first few spherical harmonics in three ways: using color on the unit sphere, as the distance from the origin, and as the distance from the unit sphere.

cm=colormaps.hsv
@interact
def _(l=slider(0,5,step_size=1)):
@interact
def _(m=slider(-l,l,default=0,step_size=1)):
sh=spherical_harmonic(l,m,theta,phi)
max2=max(flatten([[abs(spherical_harmonic(l,m,theta,phi))^2
for phi in [2*p*pi/10 for p in range(1)]]
for theta in [q*pi/10 for q in range(11)]]))
max2a=max(flatten([[1+abs(spherical_harmonic(l,m,theta,phi))^2
for phi in [2*p*pi/10 for p in range(1)]]
for theta in [q*pi/10 for q in range(11)]]))
def col(phi,theta):
return float(abs(spherical_harmonic(l,m,theta,phi))^2/max2)
sph1=spherical_plot3d(1,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shp2=spherical_plot3d(abs(sh)^2/max2,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shp3=spherical_plot3d(1+abs(sh)^2/max2a,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shp=sph1.translate((2,-2,0))+shp2+shp3.translate((-2,2,0))
show(shp)


Here are the (magnitudes of the) real and imaginary parts of the spherical harmonics, along with the overall magnitude.

@interact
def _(l=slider(0,5,step_size=1)):
@interact
def _(m=slider(-l,l,default=0,step_size=1)):
sh=spherical_harmonic(l,m,theta,phi)
mr=max(flatten([[abs(real(spherical_harmonic(l,m,theta,phi)))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
mi=max(flatten([[abs(imag(spherical_harmonic(l,m,theta,phi)))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
mx=max(flatten([[abs(spherical_harmonic(l,m,theta,phi))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
if mi==0:
mi=1
def col(phi,theta):
return float(abs(spherical_harmonic(l,m,theta,phi))/mx)
sphr=spherical_plot3d(abs(real(sh))/mr,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shpi=spherical_plot3d(abs(imag(sh))/mi,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shpa=spherical_plot3d(abs(sh)/mx,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
shp=sphr.translate((2,-2,0))+shpi+shpa.translate((-2,2,0))
show(shp)


Here are the signed values of the real and imaginary parts of the spherical harmonics, along with the overall magnitude. (The sign is indicated by color only, not by allowing the radius to become negative.)

@interact
def _(l=slider(0,5,step_size=1)):
@interact
def _(m=slider(-l,l,default=0,step_size=1)):
sh=spherical_harmonic(l,m,theta,phi)
mr=max(flatten([[abs(real(spherical_harmonic(l,m,theta,phi)))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
mi=max(flatten([[abs(imag(spherical_harmonic(l,m,theta,phi)))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
mx=max(flatten([[abs(spherical_harmonic(l,m,theta,phi))
for phi in [2*p*pi/10 for p in range(11)]]
for theta in [q*pi/10 for q in range(11)]]))
if mi==0:
mi=1
def colr(phi,theta):
return float(1/2+real(spherical_harmonic(l,m,theta,phi))/mx/2)
def coli(phi,theta):
return float(1/2+imag(spherical_harmonic(l,m,theta,phi))/mx/2)
def cola(phi,theta):
return float(1/2+abs(spherical_harmonic(l,m,theta,phi))/mx/2)
sphr=spherical_plot3d(abs(real(sh))/mr,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(colr,cm))
shpi=spherical_plot3d(abs(imag(sh))/mi,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(coli,cm))
shpa=spherical_plot3d(abs(sh)/mx,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(cola,cm))
shp=sphr.translate((2,-2,0))+shpi+shpa.translate((-2,2,0))
show(shp)


Finally, here you can graph (using color only) an arbitrary (complex!) linear combination of spherical harmonics, each entered as “$$Y(\ell,m)$$”. (Use $$I$$ for $$i\text{,}$$ and submit your combination by pressing Enter.)

cm=colormaps.hsv
l,m,theta,phi=var('l,m,theta,phi')
Y(l,m)=spherical_harmonic(l,m,theta,phi)
@interact
def _(YY=input_box(0,label="Sum =")):
def YYe(T,P):
return YY.subs(phi==P).subs(theta==T)
maxx=max(flatten([[abs(YYe(q*pi/10,2*p*pi/10))
for p in range(11)] for q in range(11)]))
if maxx==0:
maxx=1
def col(P,T):
return float(abs(YYe(T,P))/maxx)
YYg=spherical_plot3d(1,(phi,0,2*pi),(theta,0,pi),
plot_points=50,frame=False,color=(col,cm))
show(YYg)