codexnuclear-equal-volume-deformations.py
nuclear-equal-volume-deformations.py
"""Equal-volume spheroid geometry; Python 3.14, NumPy 2.3.5, Matplotlib 3.10.7.
Run from _media; the PNG is written to the current working directory.
The surfaces are geometric models, not images of individual nucleons.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({"font.size": 11, "figure.facecolor": "white"})
fig = plt.figure(figsize=(11, 4.4), dpi=120, facecolor="white")
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 65)
uu, vv = np.meshgrid(u, v)
cases = [
("Prolate", 1.8, "#258d9c", r"$Q_0>0$"),
("Spherical", 1.0, "#9ba8b4", r"$Q_0=0$"),
("Oblate", 1 / 1.8, "#d78b4c", r"$Q_0<0$"),
]
for index, (title, ratio, color, sign) in enumerate(cases, 1):
a, c = ratio ** (-1 / 3), ratio ** (2 / 3)
assert np.isclose(a * a * c, 1)
ax = fig.add_subplot(1, 3, index, projection="3d")
x = a * np.sin(vv) * np.cos(uu)
y = a * np.sin(vv) * np.sin(uu)
z = c * np.cos(vv)
ax.plot_surface(x, y, z, color=color, linewidth=0, antialiased=True,
alpha=1, shade=True, rcount=65, ccount=100)
ax.plot([0, 0], [0, 0], [-1.7, 1.7], color="#374151", lw=1, ls="--")
for angle in [0, np.pi / 2]:
ax.plot(a * np.sin(v) * np.cos(angle),
a * np.sin(v) * np.sin(angle), c * np.cos(v),
color="#354958", lw=0.7, alpha=0.6)
ax.set(xlim=(-1.7, 1.7), ylim=(-1.7, 1.7), zlim=(-1.7, 1.7))
ax.set_box_aspect((1, 1, 1))
ax.view_init(elev=16, azim=-64)
ax.set_axis_off()
ax.set_title(title + "\n" + sign, pad=-4, fontsize=14)
ax.text2D(0.5, -0.02, f"a/R = {a:.3f} c/R = {c:.3f}",
transform=ax.transAxes, ha="center", fontsize=11)
fig.suptitle("Same volume, different intrinsic shapes", fontsize=17, y=0.98)
fig.text(0.5, 0.065, r"Semiaxes $(a,a,c)$: $a^2c=R^3$ and $V=4\pi R^3/3$",
ha="center", fontsize=12)
fig.text(0.5, 0.014, "Smooth geometric surfaces; dashed line is the chosen intrinsic z axis.",
ha="center", fontsize=10, color="#374151")
fig.subplots_adjust(left=0.015, right=0.985, bottom=0.19, top=0.84, wspace=0.03)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white",
transparent=False, dpi=120)
plt.close(fig)
if __name__ == "__main__":
main()