【Python】水素原子の可視化:球面調和関数
球面調和関数
0. 概要
この記事では、シュレディンガー方程式に従う水素原子の解を描画する、という立場に立ち、球面調和関数(Spherical harmonics function)に関する情報を整理・解説する。水素原子の解のうち、動径方向に関する部分は以前の記事を参考にされたい。なお、水素原子の解の計算にはscipy(python)ライブラリの球面調和関数計算モジュール(scipy.special.sph_harm)を使用する。球面調和関数の描画はmatplotlib(python)を使用した。
pythonで球面調和関数を描画する上での注意点は下記の3点である。この記事ではこの3点について解説する。
- Scipyライブラリの仕様
- 球面調和関数の“何の情報”を描画するのが適切か?
- デフォルトのカラープロット機能では意図した描画ができない
1.を挙げた理由としては、他の方が書かれた記事でも言及されているが、特殊関数は資料によって定義の揺れが大きく(例えば参考[2,3])、公式helpを注意深く読まないと意図した計算ができないためである。
2.を挙げた理由としては、球面調和関数の描画方法はざっと調べた限りでも表1に示す通り7通りあり(参考[4])、初めて描画する際はどれを採用すべきか戸惑う可能性があるためである。
表1. 球面調和関数の描画方法(wikipediaより引用:参考[4])
1, 2.が解決したとして、実際にグラフにして描画できるかは別問題である。実際、水素原子の球面調和関数を描画する際はmatplotlibのデフォルトの機能(plot_surfaceのcmap, color等)ではz軸の値に依存した色付けになってしまい、意図した描画ができない(図1の右側の図)。水素原子の球面調和関数をプロットする際は、図1の左側の図のように球面調和関数の符号(位相)に依存した色付けをするのが適切であるが、これにはカラーパレットのカスタマイズが必要である。ただ、カラーパレットのカスタマイズ方法はscipy公式ヘルプでもしっかりとした説明がなされておらず(参考[5])、ネット上に散らばっている情報自体も日本語・英語含めて少ない。これが3.を挙げた理由である。
図1. 球面調和関数の意図した色付けと意図しない色付け
1. Scipyライブラリの仕様:球面調和関数
1-1. 球面調和関数の定義
Scipyライブラリを使用する以前に、球面調和関数がどのように定義されているかを整理する。結論から言うと、私が調べた範囲内だと(参考[1,6-12])、ランダウの教科書(参考[12])以外、球面調和関数
一方、球面調和関数の定義に使用されるルジャンドル陪多項式(Associated Legendre polynomials)
特殊関数の定義のされ方の違いについて整理した結果を表2にまとめた。
表2. 特殊関数の定義の違い
まず、シッフ、猪木・川合の量子力学の教科書(参考[6,7])では球面調和関数
Scipyの球面調和関数計算モジュールscipy.special.sph_harm(参考[1])での球面調和関数の定義について説明する。scipy.special.sph_harmでは式(8)のように球面調和関数が定義されている。一般的な引数の取り方と
以上まとめると、
サクライの量子力学の教科書(参考[8])では球面調和関数
日本語wikipediaで(参考[9])、球面調和関数
ここで、
英語wikipedia(参考[10])で、球面調和関数
式(21)~(24)で定義される球面調和関数
ランダウの教科書(参考[12])では式(25)~(27)のように球面調和関数が定義されていた。これは式(1)~(4)で定義されるものと係数
1-2. 球面調和関数計算モジュールを使用上の注意
前節1-1.で球面調和関数の定義を見比べてみたが、scipyでは
from scipy.special import sph_harm
def my_sph_harm(l, m, theta, phi):
return sph_harm(m, l, phi, theta)
2. 球面調和関数の"何の情報"を描画するのが適切か?
水素原子の解を描画しようと思った時のそもそもの興味は、下記の1~3である。ここで、電子波動関数
- 電子波動関数
の\Psi_{nlm}(r, \theta, \phi) 直交空間における分布(x, y, z) - 電子確率密度
の\rho_{nlm}(r, \theta, \phi) 直交空間における分布(x, y, z) - 電子波動関数
の\Psi_{nlm}(r, \theta, \phi) 直交空間における位相分布(x, y, z)
上記の1~3の全ての情報を知るためには動径波動関数
そこで、本記事では
ただ、私たちが高校の化学の教科書(例えば参考[18])や多くの量子化学の教科書で良く見かけるのは、表1で示した実数基底関数を用いたPolar Plots with Magnitude as Radiusによる描画である。本記事ではこの描画方法の利点と他の描画方法の違いについて主に解説する。
1~3の目的に明らかにそぐわないため、本記事では詳しく解説しないが、
2-1. Polar Plots with Magnitude as Radius
さて、
しかしながら、
これにより
- 位相
によって生じる符号(正負)に関する情報\theta, \phi - 位相
によって生じた\phi が持つ複素空間上での情報e^{im\phi}
位相
Twistar48 - Own work, CC BY-SA 4.0, https://onl.tw/BDUDwik
図2. 複素基底関数のPolar Plots with Magnitude as Radius(参考[4]より引用)
これを解決するのが
図3. 実数化した基底関数のPolar Plots with Magnitude as Radius
式(35)による基底変換は、複素基底関数系
図3では式(36)のように
つまり、図3のような実数基底関数系による表現は、z軸方向の軌道角運動量
2-2. Polar Plots
2-1.節で、
3. matplotlibでの描画:カラープロット
ここでは、2-1.節で説明したPolar Plots with Magnitude as Radiusの描画方法について説明する。0.節で触れたようにmatplotlibで球面調和関数の描画をしようとすると、球面調和関数の位相による色分けがデフォルトの機能だけではできない(図1再掲)。
図1. 球面調和関数の意図した色付けと意図しない色付け(再掲)
そこで今回は下記に示すようなコードで目的を達成した。球面調和関数を実数化し、色分けが2値化で十分な場合は、参考[21]で記載されているような方法で十分に目的は達成できる。今回は他の目的にも応用できるように連続的な色付けができる方法をとった。この方法は参考[5,23]の記事を参考にした。このとき、カラーバーとplot_surface
で別々に色の制御を行っていることに注意したい。このコードでは実数化された球面調和関数Y
の値に依存した色分けがなされる。bwr
のカラーパレットを使用した場合は図4のような色付けがなされ、jet
のカラーパレットを使用した場合は図5のような色付けがなされる。
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
"""
~~~ 中略 ~~~
"""
# --- グラフ基本設定 ---
fig = plt.figure(figsize=(7,7))
ax = fig.add_subplot(1,1,1, projection='3d')
ax.set_box_aspect((1, 1, 1))
# 色の設定
alpha = 0.7 # 透明度
color = cm.bwr # 色: blue, white, red
#color = cm.jet # 色:虹色のパレットを使用したい場合
# 色の正規化オブジェクト:norm
Max = np.maximum( np.fabs(np.amin(Y)), np.fabs(np.amax(Y)))
norm = matplotlib.colors.Normalize(vmin = -Max, vmax = Max)
# カラーバーの設定
m = cm.ScalarMappable(cmap=color, norm=norm)
cbar = fig.colorbar(m, alpha=alpha, shrink=0.4, pad=0.1)
cbar.set_label(Y_name, rotation=0, y=1.15)
ax.plot_surface(x, y, z, facecolors=color(norm(Y)) , alpha = alpha, linewidth=0, rstride=rst, cstride=cst)
図4. bwr
のカラーパレットを使用した場合の色付け
図5. jet
のカラーパレットを使用した場合の色付け
下記は方位量子数scipy.special.sph_harm
を使用しているため、任意の方位量子数
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.special import sph_harm
# カラーバーラベル、グラフタイトルを選択するための関数
def select_name(l, m):
# グラフ描画用リスト: s~f (l = 0, 1, 2, 3)
Y_name = \
["$Y\_s$", \
"$Y\_py$", "$Y\_pz$", "$Y\_px$", \
"$Y\_dxy$", "$Y\_dyz$", "$Y\_d(3z^2-r^2)$", "$Y\_dxz$", "$Y\_d(x^2-y^2)$", \
"$Y\_fy(3x^2-y^2)$", "$Y\_fxyz$", "$Y\_fy(5z^2-r^2)$", "$Y\_f(5z^3-3zr^2)$", \
"$Y\_fx(5z^2-r^2)$", "$Y\_fz(x^2-y^2)$", "$Y\_fx(x^2-3y^2)$"]
orbit_name = \
["$s$", \
"$p_y$", "$p_z$", "$p_x$", \
"$d_{xy}$", "$d_{yz}$", "$d_{(3z^2-r^2)}$", "$d_{xz}$", "$d_{(x^2-y^2)}$", \
"$f_{y(3x^2-y^2)}$", "$f_{xyz}$", "$f_{y(5z^2-r^2)}$", "$f_{(5z^3-3zr^2)}$", \
"$f_{x(5z^2-r^2)}$", "$f_{z(x^2-y^2)}$", "$f_{x(x^2-3y^2)}$"]
# l_maxが4より大きい場合はY_nameとtitle_nameに空の名前を追加
if l >= 4:
Y_name.append("")
orbit_name.append("")
# Y_name, title_nameのインデックスの選択
if l <= 3:
i=-1
for p in range(0, l+1, 1):
for q in range(-p, p+1, 1):
if p != l or q<= m:
i = i+1
else:
i = 16
return Y_name[i], orbit_name[i]
# 球面調和関数のノーテーションや文字を物理の教科書用にカスタマイズ
def my_sph_harm(l, m, theta, phi):
return sph_harm(m, l, phi, theta)
# 実数化した球面調和関数を算出する関数:関数の中でmy_sph_harm()使用
def real_sph_harm(l, m, theta, phi):
if m < 0:
# m < 0であることに注意: np.fabs(m) = -m
Y = np.real(1.j * np.sqrt(1/2) * (my_sph_harm(l,m, theta, phi) + (-1)**(-m+1) * my_sph_harm(l, -m, theta, phi)))
if m == 0:
Y = np.real(my_sph_harm(l, m, theta, phi))
if m > 0:
Y = np.real(np.sqrt(1/2) * (my_sph_harm(l,-m, theta, phi) + (-1)**m * my_sph_harm(l, m, theta, phi)))
return Y
# (r,Θ,φ)空間から(x,y,z)空間への射影
def polar(r, theta, phi):
x = r * np.sin(theta) * np.cos(phi)
y = r * np.sin(theta) * np.sin(phi)
z = r * np.cos(theta)
return x, y, z
# グラフの描画用の関数
def plot_surf(x, y, z, Y, Y_name, title_name, filename, l, m, ax_lim, rst, cst):
# --- グラフ基本設定 ---
plt.rcParams["xtick.labelsize"] = 10 # 目盛りのフォントサイズ
plt.rcParams["ytick.labelsize"] = 10 # 目盛りのフォントサイズ
plt.rcParams["axes.labelsize"] = 13 # 軸ラベルのフォントサイズ
plt.rcParams["axes.titlesize"] = 30 # グラフタイトルのフォントサイズ
plt.rcParams["mathtext.fontset"] = "cm" # TeXのフォント, デフォルト:dejavusans
plt.rcParams["figure.dpi"] = 100 # dpi(dots per inch):解像度
fig = plt.figure(figsize=(7,7))
ax = fig.add_subplot(1,1,1, projection='3d')
ax.set_box_aspect((1, 1, 1))
# 色の設定
alpha = 0.7 # 透明度
color = cm.bwr # 色: blue, white, red
#color = cm.jet # 色: 虹色
# 色の正規化オブジェクト:norm
Max = np.maximum( np.fabs(np.amin(Y)), np.fabs(np.amax(Y)))
norm = matplotlib.colors.Normalize(vmin = -Max, vmax = Max)
# カラーバーの設定
m = cm.ScalarMappable(cmap=color, norm=norm)
cbar = fig.colorbar(m, alpha=alpha, shrink=0.4, pad=0.1)
cbar.set_label(Y_name, rotation=0, y=1.15)
# サーフェスプロット
if l == 0 and m ==0 :
# --- 例外処理をしている理由 ---
# l==0 and m==0 はs軌道のとき
# s軌道は球面調和関数の大きさが常に一定なのでbwrのパレットを使用すると真っ白な球になってしまう
# norm(Y)が -MaxとMaxの中点0になる
# 実数化球面調和関数が正の値を持つときは赤い色付けをしたいため、例外処理を行っている
ax.plot_surface(x, y, z, color="red" , alpha = alpha, linewidth=0, rstride=rst, cstride=cst)
else:
ax.plot_surface(x, y, z, facecolors=color(norm(Y)) , alpha = alpha, linewidth=0, rstride=rst, cstride=cst)
# 軸範囲、ラベル、グラフタイトル
ax.set_xlim(-ax_lim, ax_lim)
ax.set_ylim(-ax_lim, ax_lim)
ax.set_zlim(-ax_lim, ax_lim)
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_zlabel('$z$')
ax.set_title(title_name)
# 図の保存
fig.savefig(filename)
plt.show()
plt.close()
return 0
# ----------- Input Parameter ---------------------------------------------
l = 2 # 方位量子数, 0以上の整数値
m = 1 # 磁気量子数, -l<= m <=l を満たす整数
ax_lim = 0.5 # グラフの描画範囲
rst = 1 # rstride:プロットのサンプリング間隔, 推奨値は1~3
cst = 1 # cstride:プロットのサンプリング間隔, 推奨値は1~3
N = 101 # theta, phiの分割数, 0以上の整数値
filename = "好きな名前" #保存する図の名前
# ------------- 補足 ---------------------------------------------------------
# m : -l<= m <=l を満たす整数が指定されていない場合は多分エラーになる。
# ax_lim: グラフの描画範囲が狭いと感じたらこれを大きくとること
# l に4以上を指定した場合はグラフタイトル、カラーバーのラベルが表示されない。グラフ描画自体はできる。
# ------------- 計算が遅いと感じたときにすること ----------------------------------------
# グラフの描画が計算速度のボトルネックになっている。
# rst, cstを大きくとることで計算速度は速くなる。
# ただし、rst, cstを大きくするとがグラフは粗くなる。
# rst, cstの推奨値は1~3。これ以上大きくとるとグラフが粗くなりすぎる。
# theta, phi: 定義域設定
theta_min = 0.0
theta_max = np.pi
phi_min = 0.0
phi_max = 2.0 * np.pi
# theta, phi: メッシュ作成
theta_a = np.linspace(theta_min, theta_max, N)
phi_a = np.linspace(phi_min, phi_max, N)
theta, phi = np.meshgrid(theta_a, phi_a)
# 計算
Y_real = real_sph_harm(l, m, theta, phi)
#r_tilde = Y_real**2
r_tilde = np.fabs(Y_real)
x, y, z = polar(r_tilde, theta, phi)
# カラーバーラベルとタイトルネームの取得
Y_name, title_name = select_name(l, m)
# グラフ描画
plot_surf(x, y, z, Y_real, Y_name, title_name, filename, l, m, ax_lim, rst, cst)
下記はl_max
で与えた方位量子数に対し、0<= l <=l_max
を満たすような方位量子数(l_max+1)**2
個のグラフが生成されるのでl_max
に大きな値を入れすぎると大量のグラフが生成されてしまうので注意されたい。
複数のグラフを同時生成するサンプルコード
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.special import sph_harm
# 球面調和関数のノーテーションや文字を物理の教科書用にカスタマイズ
def my_sph_harm(l, m, theta, phi):
return sph_harm(m, l, phi, theta)
# 実数化した球面調和関数を算出する関数:関数の中でmy_sph_harm()使用
def real_sph_harm(l, m, theta, phi):
if m < 0:
# m < 0であることに注意: np.fabs(m) = -m
Y = np.real(1.j * np.sqrt(1/2) * (my_sph_harm(l,m, theta, phi) + (-1)**(-m+1) * my_sph_harm(l, -m, theta, phi)))
if m == 0:
Y = np.real(my_sph_harm(l, m, theta, phi))
if m > 0:
Y = np.real(np.sqrt(1/2) * (my_sph_harm(l,-m, theta, phi) + (-1)**m * my_sph_harm(l, m, theta, phi)))
return Y
# (r,Θ,φ)空間から(x,y,z)空間への射影
def polar(r, theta, phi):
x = r * np.sin(theta) * np.cos(phi)
y = r * np.sin(theta) * np.sin(phi)
z = r * np.cos(theta)
return x, y, z
# グラフの描画用の関数
def plot_surf(x, y, z, Y, Y_name, graph_name, i, ax_lim, rst, cst):
# --- グラフ基本設定 ---
plt.rcParams["xtick.labelsize"] = 10 # 目盛りのフォントサイズ
plt.rcParams["ytick.labelsize"] = 10 # 目盛りのフォントサイズ
plt.rcParams["axes.labelsize"] = 13 # 軸ラベルのフォントサイズ
plt.rcParams["axes.titlesize"] = 30 # グラフタイトルのフォントサイズ
plt.rcParams["mathtext.fontset"] = "cm" # TeXのフォント, デフォルト:dejavusans
plt.rcParams["figure.dpi"] = 100 # dpi(dots per inch):解像度
fig = plt.figure(figsize=(7,7))
ax = fig.add_subplot(1,1,1, projection='3d')
ax.set_box_aspect((1, 1, 1))
# 色の設定
alpha = 0.7 # 透明度
color = cm.bwr # 色: blue, white, red
# 色の正規化オブジェクト:norm
Max = np.maximum( np.fabs(np.amin(Y)), np.fabs(np.amax(Y)))
norm = matplotlib.colors.Normalize(vmin = -Max, vmax = Max)
# カラーバーの設定
m = cm.ScalarMappable(cmap=color, norm=norm)
cbar = fig.colorbar(m, alpha=alpha, shrink=0.4, pad=0.1)
cbar.set_label(Y_name, rotation=0, y=1.15)
# サーフェスプロット
if Y_name == "$Y\_s$" :
# --- 例外処理をしている理由 ---
# s軌道は球面調和関数の大きさが常に一定なのでbwrのパレットを使用すると真っ白な球になってしまう
# norm(Y)が -MaxとMaxの中点0になる
# 実数化球面調和関数が正の値を持つときは赤い色付けをしたいため、例外処理を行っている
ax.plot_surface(x, y, z, color="red" , alpha = alpha, linewidth=0, rstride=rst, cstride=cst)
else:
ax.plot_surface(x, y, z, facecolors=color(norm(Y)) , alpha = alpha, linewidth=0, rstride=rst, cstride=cst)
# 軸範囲、ラベル、グラフタイトル
ax.set_xlim(-ax_lim, ax_lim)
ax.set_ylim(-ax_lim, ax_lim)
ax.set_zlim(-ax_lim, ax_lim)
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_zlabel('$z$')
ax.set_title(graph_name)
# 図の保存
name = graph_name.replace('$', '') # 文字列から $ を除去
name = name.replace('{', '') # 文字列から { を除去
name = name.replace('}', '') # 文字列から } を除去
if i <= 15:
# 0<= i <=15 : s~f軌道
fig.savefig(name)
else:
# 16 <= i: g軌道以降
filename = "Orbit_"
filename = filename + str(i)
fig.savefig(filename)
plt.show()
plt.close()
return 0
# ----------- Input Parameter ---------------------------------------------
l_max = 3 # 方位量子数lの最大値, 0以上の整数値
r_flag = 1 # 0 なら実数化球面調和関数の2乗が半径、1 なら実数化球面調和関数の絶対値が半径
ax_lim = 0.5 # グラフの描画範囲。r_flag=0 なら0.3程度、r_flag=0 なら0.5程度の値が良い
rst = 1 # rstride:プロットのサンプリング間隔, 推奨値は1~3
cst = 1 # cstride:プロットのサンプリング間隔, 推奨値は1~3
N = 101 # theta, phiの分割数, 0以上の整数値
# ------------- 補足 ---------------------------------------------------------
# l_max : 最も重要なインプット
# r_flag: 0 か 1 以外の値が指定されると実数化球面調和関数の2乗が半径になる。
# ax_lim: グラフの描画範囲が狭いと感じたらこれを大きくとること
# (l_max + 1)**2 個のグラフが出力される。
# l_max に4以上を指定した場合はグラフタイトル、カラーバーのラベルが表示されない。グラフ描画自体はできる。
# l_max にあまりに巨大な数を入力すると画像が大量生成されて大変なことになる。
# l_max=4 で25個のグラフ、l_max=5 で36個のグラフが生成される。
# ------------- 計算が遅いと感じたときにすること ----------------------------------------
# グラフの描画が計算速度のボトルネックになっている。
# rst, cstを大きくとることで計算速度は速くなる。
# ただし、rst, cstを大きくするとがグラフは粗くなる。
# rst, cstの推奨値は1~3。これ以上大きくとるとグラフが粗くなりすぎる。
# theta, phi: 定義域設定
theta_min = 0.0
theta_max = np.pi
phi_min = 0.0
phi_max = 2.0 * np.pi
# theta, phi: メッシュ作成
theta_a = np.linspace(theta_min, theta_max, N)
phi_a = np.linspace(phi_min, phi_max, N)
theta, phi = np.meshgrid(theta_a, phi_a)
# グラフ描画用リスト: s~f (l = 0, 1, 2, 3)
Y_name = \
["$Y\_s$", \
"$Y\_py$", "$Y\_pz$", "$Y\_px$", \
"$Y\_dxy$", "$Y\_dyz$", "$Y\_d(3z^2-r^2)$", "$Y\_dxz$", "$Y\_d(x^2-y^2)$", \
"$Y\_fy(3x^2-y^2)$", "$Y\_fxyz$", "$Y\_fy(5z^2-r^2)$", "$Y\_f(5z^3-3zr^2)$", \
"$Y\_fx(5z^2-r^2)$", "$Y\_fz(x^2-y^2)$", "$Y\_fx(x^2-3y^2)$"]
graph_name = \
["$s$", \
"$p_y$", "$p_z$", "$p_x$", \
"$d_{xy}$", "$d_{yz}$", "$d_{(3z^2-r^2)}$", "$d_{xz}$", "$d_{(x^2-y^2)}$", \
"$f_{y(3x^2-y^2)}$", "$f_{xyz}$", "$f_{y(5z^2-r^2)}$", "$f_{(5z^3-3zr^2)}$", \
"$f_{x(5z^2-r^2)}$", "$f_{z(x^2-y^2)}$", "$f_{x(x^2-3y^2)}$"]
# l_maxが4より大きい場合はY_nameとgraph_nameに空の名前を追加
if l_max >= 4:
for i in range(16, (l_max+1)**2+1, 1):
Y_name.append("")
graph_name.append("")
i = 0 # Y_name, graph_nameのインデックス
for l in range(0, l_max+1, 1):
for m in range(-l, l+1, 1):
Y_real = real_sph_harm(l, m, theta, phi)
if r_flag == 0 or r_flag != 1:
r_tilde = Y_real**2
elif r_flag == 1:
r_tilde = np.fabs(Y_real)
x, y, z = polar(r_tilde, theta, phi)
plot_surf(x, y, z, Y_real, Y_name[i], graph_name[i], i, ax_lim, rst, cst)
i = i + 1
このコードを使用して描いたs~f軌道のグラフを図6,7に示す。他の方が書かれた記事で掲載されていもの(参考[21,24])と同等のグラフが得られており、問題なくプログラムを作成できていることが確認できた。図6は式(36)の定義を採用して描いたグラフで、図7は式(37)の定義を採用して描いたグラフである。軌道の命名規則は分かりにくいが参考[25]の'Real spherical harmonics'の項を参考にした。
図6. 実数化された球面調和関数:
図7. 実数化された球面調和関数:
動作環境
・python 3.9.13
・IPython 8.4.0
・scipy 1.7.3
・matplotlib 3.5.2
・numpy 1.21.5
・Anaconda 4.14.0
・Spyder 5.9.2
・Windows10 64bit
参考
[1]. scipy_special.sph_harm(scipy公式ヘルプ)(参照2022-09-23)
[2]. 【Python】水素原子の解の描画:ラゲール陪多項式計算モジュール(参照2022-09-23)
[3]. Juliaで特殊関数を使う(参照2022-09-23)
[4]. Table of spherical harmonics(英語wikipedia)(参照2022-09-23)
[5]. 3D surface (checkerboard)(matplotlib公式ヘルプ)(参照2022-09-23)
[6]. Schiff. 量子力学(上). 吉岡書店, 2004, p.88-93.
[7]. 猪木, 川合. 量子力学Ⅰ. 講談社サイエンティフィク, 2010, p.132-135.
[8]. J.J.Sakurai. 現代の量子力学(上). 吉岡書店, 2006, p.347-348.
[9]. 球面調和関数(日本語wikipedia)(参照2022-09-23)
[10]. Spherical harmonics(英語wikipedia)(参照2022-09-23)
[11]. Associated Legendre polynomials(英語wikipedia)(参照2022-09-23)
[12]. Landau, Lifshitz. 量子力学1(非相対論的理論), 東京図書, 1991, p.105-109.
[13]. Landau, Lifshitz. 量子力学2(非相対論的理論), 東京図書, 1991, p.521-534.
[14]. 球面調和関数とその可視化(参照2022-09-23)
[15]. A.Szabo. 新しい量子化学(上)―電子構造の理論入門―. 東京大学出版会.
[16]. 朽津. 量子化学ノート. 分子化学アーカイブス(AC0016), 2013, p.129-142.(参照2022-09-23)
[17]. 日曜化学(3):分子軌道法と可視化(Python/matplotlib)(参照2022-09-23)
[18]. 卜部. 化学Ⅰ・Ⅱの新研究. 三省堂, 2005, p.26.
[19]. 色空間(日本語wikipedia)(参照2022-09-23)
[20]. HSV色空間(日本語wikipedia)(参照2022-09-23)
[21]. 日曜化学:量子力学の基本と球面調和関数の可視化(Python/matplotlib)(参照2022-09-23)
[22]. 武内. 量子力学Ⅰ/球面調和関数(筑波大学講義ノート).(参照2022-09-23)
[23]. Colorbar for matplotlib plot_surface using facecolors(stack overflow)(参照2022-09-23)
[24]. Juliaで可視化:水素原子(参照2022-09-23)
[25]. Table of spherical harmonics(英語wikipedia)(参照2022-09-23)
Discussion