{"spec_id":"line-reaction-coordinate","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nline-reaction-coordinate: Reaction Coordinate Energy Diagram\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 89/100 | Updated: 2026-06-24\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom scipy.interpolate import PchipInterpolator\n\n\n# Theme tokens — Imprint palette\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\"\n\nBRAND = \"#009E73\"  # Imprint position 1 — first (and only) data series\nEA_COLOR = \"#AE3030\"  # Imprint position 5 — semantic red for activation barrier\nDH_COLOR = \"#4467A3\"  # Imprint position 3 — blue for enthalpy change\n\nsns.set_theme(\n    context=\"notebook\",\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.15,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data — single-step exothermic reaction: Ea = 70 kJ/mol, ΔH = −30 kJ/mol\nreactant_energy = 50.0\ntransition_energy = 120.0\nproduct_energy = 20.0\n\ncontrol_x = np.array([0.0, 0.12, 0.22, 0.35, 0.47, 0.59, 0.72, 0.82, 0.90, 1.0])\ncontrol_y = np.array(\n    [\n        reactant_energy,\n        reactant_energy,\n        reactant_energy + 2,\n        85,\n        transition_energy,\n        85,\n        product_energy + 5,\n        product_energy,\n        product_energy,\n        product_energy,\n    ]\n)\n\nreaction_coord = np.linspace(0, 1, 500)\nspline = PchipInterpolator(control_x, control_y)\nenergy = spline(reaction_coord)\n\ndf = pd.DataFrame({\"Reaction Coordinate\": reaction_coord, \"Potential Energy (kJ/mol)\": energy})\n\n# Key state markers evaluated on the spline\nkey_x = np.array([0.10, 0.47, 0.88])\nkey_states = pd.DataFrame({\"Reaction Coordinate\": key_x, \"Potential Energy (kJ/mol)\": spline(key_x)})\n\n# Figure-level seaborn API — relplot for consistent figure layout management\ng = sns.relplot(\n    data=df,\n    x=\"Reaction Coordinate\",\n    y=\"Potential Energy (kJ/mol)\",\n    kind=\"line\",\n    color=BRAND,\n    linewidth=2.5,\n    height=4.5,\n    aspect=16 / 9,\n)\ng.figure.set_dpi(400)\ng.figure.set_facecolor(PAGE_BG)\nax = g.axes.flat[0]\nax.set_facecolor(PAGE_BG)\n\n# Seaborn scatter layer marking reactant, transition state, and product positions\nsns.scatterplot(\n    data=key_states,\n    x=\"Reaction Coordinate\",\n    y=\"Potential Energy (kJ/mol)\",\n    color=BRAND,\n    s=80,\n    zorder=5,\n    legend=False,\n    ax=ax,\n)\n\nax.fill_between(reaction_coord, energy, alpha=0.08, color=BRAND, zorder=2)\n\n# Horizontal dashed reference lines at reactant and product energy levels\nax.hlines(reactant_energy, xmin=-0.02, xmax=0.18, color=INK_SOFT, linestyle=\"--\", linewidth=1.2, alpha=0.6)\nax.hlines(product_energy, xmin=0.82, xmax=1.02, color=INK_SOFT, linestyle=\"--\", linewidth=1.2, alpha=0.6)\n\n# Species labels — direct annotation on chart\nax.text(0.02, reactant_energy + 3, \"Reactants\\n(50 kJ/mol)\", fontsize=9, fontweight=\"bold\", color=INK, va=\"bottom\")\nax.text(\n    0.98, product_energy - 3, \"Products\\n(20 kJ/mol)\", fontsize=9, fontweight=\"bold\", color=INK, va=\"top\", ha=\"right\"\n)\nax.text(\n    0.47,\n    transition_energy + 2,\n    \"Transition State\\n(120 kJ/mol)\",\n    fontsize=9,\n    fontweight=\"bold\",\n    color=INK,\n    va=\"bottom\",\n    ha=\"center\",\n)\n\n# Activation energy arrow (Ea)\nea_x = 0.13\nax.annotate(\n    \"\",\n    xy=(ea_x, transition_energy),\n    xytext=(ea_x, reactant_energy),\n    arrowprops={\"arrowstyle\": \"<->\", \"color\": EA_COLOR, \"lw\": 2.0, \"shrinkA\": 0, \"shrinkB\": 0},\n)\nax.text(\n    ea_x - 0.02,\n    (reactant_energy + transition_energy) / 2,\n    f\"$E_a$ = {transition_energy - reactant_energy:.0f} kJ/mol\",\n    fontsize=8,\n    color=EA_COLOR,\n    fontweight=\"bold\",\n    ha=\"right\",\n    va=\"center\",\n    bbox={\"boxstyle\": \"round,pad=0.3\", \"facecolor\": ELEVATED_BG, \"edgecolor\": \"none\", \"alpha\": 0.9},\n)\n\n# Enthalpy change arrow (ΔH)\ndh_x = 0.82\nax.annotate(\n    \"\",\n    xy=(dh_x, product_energy),\n    xytext=(dh_x, reactant_energy),\n    arrowprops={\"arrowstyle\": \"<->\", \"color\": DH_COLOR, \"lw\": 2.0, \"shrinkA\": 0, \"shrinkB\": 0},\n)\nax.text(\n    dh_x - 0.02,\n    (reactant_energy + product_energy) / 2,\n    f\"$\\\\Delta H$ = {product_energy - reactant_energy:.0f} kJ/mol\",\n    fontsize=8,\n    color=DH_COLOR,\n    fontweight=\"bold\",\n    ha=\"right\",\n    va=\"center\",\n    bbox={\"boxstyle\": \"round,pad=0.3\", \"facecolor\": ELEVATED_BG, \"edgecolor\": \"none\", \"alpha\": 0.9},\n)\n\n# Style\ntitle = \"line-reaction-coordinate · python · seaborn · anyplot.ai\"\nax.set_xlabel(\"Reaction Coordinate\", fontsize=10, color=INK)\nax.set_ylabel(\"Potential Energy (kJ/mol)\", fontsize=10, color=INK)\nax.set_title(title, fontsize=12, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\nsns.despine(ax=ax)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_color(INK_SOFT)\nax.set_xlim(-0.02, 1.02)\nax.set_ylim(0, 145)\nax.set_xticks([])\nax.xaxis.grid(False)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\ng.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}