# fig-cap: Electron configurations and ground-state terms for H–Ne. Each box represents an orbital (either $s$ or $p$), and arrows denote electron spins. According to Hund’s rules, orbitals are filled to maximize total spin and orbital angular momentum before pairing occurs.
import matplotlib.pyplot as plt
import matplotlib.patches as patches
plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 15
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 14)
ax.set_ylim(-4.5, 6)
ax.axis('off')
def draw_orbital_box(ax, x, y, width=0.6, height=0.6, filled=False, filled_once=False, arrows=''):
"""Draw a single orbital box with optional electron arrows"""
color = 'aliceblue' if filled_once else ('lightblue' if filled else 'white')
rect = patches.Rectangle((x, y), width, height, linewidth=0.5,
edgecolor='black', facecolor=color)
ax.add_patch(rect)
# Add arrows for electrons
if arrows:
ax.text(x + width/2, y + height/2, arrows, ha='center', va='center',
fontsize=14, fontweight='bold')
def draw_element_config(ax, x_start, y_start, element, s1_config, s2_config, p2_config, term_symbol):
"""Draw complete electron configuration for an element"""
box_size = 0.6
spacing = 0.65
# Element label
ax.text(x_start + 1.2, y_start + 2.2, element, ha='center', va='center',
fontsize=12, fontweight='bold')
# Orbital labels
ax.text(x_start + 0.3, y_start + 1.7, r'$s$', ha='center', va='center', fontsize=12)
if len(p2_config) > 0:
ax.text(x_start + 1.5, y_start + 1.7, r'$p$', ha='center', va='center', fontsize=12)
# s1 orbital
draw_orbital_box(ax, x_start, y_start + 0.2, box_size, box_size,
filled=(s1_config != ''), filled_once=(s1_config.count('↑') + s1_config.count('↓')==1), arrows=s1_config)
# s2 orbital
draw_orbital_box(ax, x_start, y_start + 0.8, box_size, box_size,
filled=(s2_config != ''), filled_once=(s2_config.count('↑') + s2_config.count('↓')==1), arrows=s2_config)
# p2 orbitals
for i, p_arrows in enumerate(p2_config):
draw_orbital_box(ax, x_start + spacing + i*box_size, y_start + 0.8,
box_size, box_size, filled=(p_arrows != ''), filled_once=(p_arrows.count('↑') + p_arrows.count('↓')==1), arrows=p_arrows)
# Term symbol
ax.text(x_start + 1.7, y_start + 0.3, term_symbol, ha='center', va='center',
fontsize=11)
# Period 1
draw_element_config(ax, 0.5, 3, 'H', '↑', '', ['', '', ''], r'1$^2S_{1/2}$')
draw_element_config(ax, 3.5, 3, 'He', '↑↓', '', ['', '', ''], r'1$^1S_0$')
# Period 2
y_pos = 0
elements = [
('Li', '↑↓', '↑', ['', '', ''], r'2$^2S_{1/2}$', 0.5),
('Be', '↑↓', '↑↓', ['', '', ''], r'2$^1S_0$', 3.5),
('B', '↑↓', '↑↓', ['↑', '', ''], r'2$^2P_{1/2}$', 6.5),
('C', '↑↓', '↑↓', ['↑', '↑', ''], r'2$^3P_0$', 9.5),
('N', '↑↓', '↑↓', ['↑', '↑', '↑'], r'2$^4S_{3/2}$', 0.5),
('O', '↑↓', '↑↓', ['↑↓', '↑', '↑'], r'2$^3P_2$', 3.5),
('F', '↑↓', '↑↓', ['↑↓', '↑↓', '↑'], r'2$^2P_{3/2}$', 6.5),
('Ne', '↑↓', '↑↓', ['↑↓', '↑↓', '↑↓'], r'2$^1S_0$', 9.5),
]
for element, s1_conf, s2_conf, p2_conf, term, x_pos in elements:
if (element=='N'): y_pos=-3
draw_element_config(ax, x_pos, y_pos, element, s1_conf, s2_conf, p2_conf, term)
# Add quantum number labels on the left
ax.text(0, 3.45, 'K', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(0, 4.05, 'L', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(0, .45, 'K', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(0, 1.05, 'L', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(0, -2.55, 'K', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(0, -1.95, 'L', ha='center', va='center', fontsize=10, fontweight='bold')
plt.tight_layout()
plt.show()