codexlinear-rigid-rotor-levels-and-transitions.py
linear-rigid-rotor-levels-and-transitions.py
"""Dimensionless linear-rotor energy ladder and dipole-allowed line positions.
Run from _media with Python 3.14, matplotlib 3.10.7 and numpy 2.3.5.
All plotted quantities are exact model values; stick heights carry no intensity.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({"font.size": 12, "axes.spines.top": False,
"axes.spines.right": False, "figure.facecolor": "white",
"axes.facecolor": "white", "savefig.facecolor": "white"})
fig, (levels, spectrum) = plt.subplots(
1, 2, figsize=(9.4, 5.5), gridspec_kw={"width_ratios": [1.3, 1]},
layout="constrained")
j = np.arange(5)
energy = j * (j + 1)
for quantum, value in zip(j, energy):
levels.hlines(value, 0.05, 1.05, color="#243e63", linewidth=2.3)
levels.text(1.1, value, f"J = {quantum}: {2 * quantum + 1} states",
va="center", fontsize=11)
colors = ["#167b89", "#3665ad", "#916db1", "#c06c29"]
for lower, color in zip(range(4), colors):
x = 0.17 + 0.24 * lower
y0, y1 = energy[lower:lower + 2]
levels.annotate("", xy=(x, y1), xytext=(x, y0),
arrowprops={"arrowstyle": "->", "color": color,
"lw": 2.4, "shrinkA": 3, "shrinkB": 3})
levels.text(x + 0.04, (y0 + y1) / 2, f"{2 * (lower + 1)}hB",
color=color, va="center", fontsize=10)
levels.set(xlim=(0, 2.42), ylim=(-1, 22), xticks=[],
yticks=energy, ylabel=r"Energy $E_J/(hB)$",
title=r"Levels: $J(J+1)$")
levels.spines["bottom"].set_visible(False)
for lower, color in zip(range(4), colors):
frequency = 2 * (lower + 1)
spectrum.vlines(frequency, 0, 1, color=color, lw=3)
spectrum.text(frequency, 1.05, f"{lower} → {lower + 1}",
ha="center", color=color, fontsize=11)
spectrum.annotate("", xy=(4, 0.7), xytext=(2, 0.7),
arrowprops={"arrowstyle": "<->", "color": "#333333"})
spectrum.text(3, 0.76, r"spacing $2B$", ha="center", fontsize=11)
spectrum.set(xlim=(0, 9.5), ylim=(0, 1.33), yticks=[],
xticks=[0, 2, 4, 6, 8], xlabel=r"Frequency $\nu/B$",
title=r"Absorption: $\Delta J=+1$")
spectrum.spines["left"].set_visible(False)
fig.suptitle("Linear rigid rotor: larger level gaps, regular spectral spacing",
fontsize=14)
fig.supxlabel("Field-free spin-free model • Equal-height sticks show positions only",
fontsize=10)
fig.savefig(Path(__file__).with_suffix(".png").name, dpi=120,
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()