{"spec_id":"line-tanabe-sugano","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-tanabe-sugano: Tanabe-Sugano Diagram for Crystal Field Theory\nLibrary: matplotlib 3.11.2 | Python 3.13.15\nQuality: 90/100 | Created: 2026-10-01\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.lines import Line2D\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nSPIN_ALLOWED = \"#009E73\"  # Imprint palette position 1 — ALWAYS first series\nSPIN_FORBIDDEN = \"#C475FD\"  # Imprint palette position 2\n\n# Data — octahedral Tanabe-Sugano matrices for d² (V³⁺), energies in units of the\n# Racah parameter B with the Racah A dropped as an additive constant. Each block\n# holds the terms of one symmetry; diagonalizing it gives the avoided crossings.\nc_over_b = 4.5\nfield_strength = np.linspace(0.0, 40.0, 361)  # Δ_o / B\nflat = np.ones_like(field_strength)\noff_e = 2 * np.sqrt(3) * flat\noff_a1 = np.sqrt(6) * (2 + c_over_b) * flat\n\nblocks = [\n    ([\"$^{3}T_{1g}(F)$\", \"$^{3}T_{1g}(P)$\"], True, [[-5 * flat, 6 * flat], [6 * flat, 4 + field_strength]]),\n    ([\"$^{3}T_{2g}$\"], True, [[-8 + field_strength]]),\n    ([\"$^{3}A_{2g}$\"], True, [[-8 + 2 * field_strength]]),\n    (\n        [\"$^{1}E_{g}(D)$\", \"$^{1}E_{g}(G)$\"],\n        False,\n        [[(1 + 2 * c_over_b) * flat, off_e], [off_e, 2 * c_over_b + 2 * field_strength]],\n    ),\n    (\n        [\"$^{1}T_{2g}(D)$\", \"$^{1}T_{2g}(G)$\"],\n        False,\n        [[(1 + 2 * c_over_b) * flat, off_e], [off_e, 2 * c_over_b + field_strength]],\n    ),\n    ([\"$^{1}T_{1g}$\"], False, [[4 + 2 * c_over_b + field_strength]]),\n    (\n        [\"$^{1}A_{1g}(G)$\", \"$^{1}A_{1g}(S)$\"],\n        False,\n        [[(8 + 4 * c_over_b) * flat, off_a1], [off_a1, 10 + 5 * c_over_b + 2 * field_strength]],\n    ),\n]\n\nterms = []\nfor labels, spin_allowed, rows in blocks:\n    roots = np.linalg.eigvalsh(np.moveaxis(np.array(rows), -1, 0))\n    for root, label in zip(roots.T, labels, strict=True):\n        terms.append((label, spin_allowed, root))\n\nground_energy = np.min([root for _, _, root in terms], axis=0)\n\n# Plot — square canvas, near-square plot area with a gutter for the term labels\nfield_max, energy_max = 40.0, 80.0\nlabel_nudge = {\"$^{3}T_{1g}(F)$\": 2.6, \"$^{1}E_{g}(D)$\": 2.5, \"$^{1}T_{2g}(D)$\": -2.5}\n\nfig, ax = plt.subplots(figsize=(6, 6), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\nfig.subplots_adjust(left=0.095, right=0.975, bottom=0.085, top=0.90)\n\nfor label, spin_allowed, root in terms:\n    reduced_energy = root - ground_energy\n    ax.plot(\n        field_strength,\n        reduced_energy,\n        color=SPIN_ALLOWED if spin_allowed else SPIN_FORBIDDEN,\n        linewidth=2.8 if spin_allowed else 1.4,\n        linestyle=\"-\" if spin_allowed else (0, (5, 3)),\n        zorder=3,\n    )\n    # Term label with a leader line, at the right edge or where the curve leaves the frame\n    last = np.flatnonzero(reduced_energy <= energy_max)[-1]\n    if last == field_strength.size - 1:\n        anchor = (field_max, reduced_energy[-1])\n        text_at = (field_max + 1.6, reduced_energy[-1] + label_nudge.get(label, 0.0))\n        ha, va = \"left\", \"center\"\n    else:\n        anchor = (field_strength[last], energy_max)\n        text_at = (field_strength[last] - 2.2, energy_max - 0.5)\n        ha, va = \"right\", \"top\"\n    ax.annotate(\n        label,\n        xy=anchor,\n        xytext=text_at,\n        ha=ha,\n        va=va,\n        fontsize=9,\n        color=INK,\n        arrowprops={\"arrowstyle\": \"-\", \"linewidth\": 0.7, \"color\": INK_SOFT, \"shrinkA\": 2},\n    )\n\n# Style\nax.set_xlim(0, 46.5)\nax.set_ylim(0, energy_max)\nax.set_xticks(np.arange(0, 41, 10))\nax.set_yticks(np.arange(0, 81, 20))\nax.set_xlabel(\"Ligand-Field Strength  $\\\\Delta_o/B$\", fontsize=10, color=INK)\nax.set_ylabel(\"Term Energy  $E/B$\", fontsize=10, color=INK)\nax.set_title(\n    \"line-tanabe-sugano · python · matplotlib · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK, pad=26\n)\nax.text(\n    0.5,\n    1.012,\n    \"$d^{2}$ (V$^{3+}$) in an octahedral field, $C/B$ = 4.5\",\n    transform=ax.transAxes,\n    ha=\"center\",\n    va=\"bottom\",\n    fontsize=10,\n    color=INK_SOFT,\n)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, labelcolor=INK_SOFT)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor side in (\"left\", \"bottom\"):\n    ax.spines[side].set_color(INK_SOFT)\nax.set_axisbelow(True)\nax.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\nhandles = [\n    Line2D([], [], color=SPIN_ALLOWED, linewidth=2.8, label=\"Spin-allowed (triplet)\"),\n    Line2D([], [], color=SPIN_FORBIDDEN, linewidth=1.4, linestyle=(0, (5, 3)), label=\"Spin-forbidden (singlet)\"),\n]\nlegend = ax.legend(handles=handles, loc=\"lower right\", bbox_to_anchor=(0.865, 0.02), fontsize=8)\nlegend.get_frame().set_facecolor(ELEVATED_BG)\nlegend.get_frame().set_edgecolor(INK_SOFT)\nplt.setp(legend.get_texts(), color=INK_SOFT)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}