codexcatalyst-forward-reverse-rate-ratios.py
catalyst-forward-reverse-rate-ratios.py
"""Generate catalyst-forward-reverse-rate-ratios.png in the current directory.
Original fixed-temperature toy model, with common Eyring prefactor factored out.
Tested with Python 3.14.4, NumPy 2.3.5, and Matplotlib 3.10.7. Run from _media.
"""
import math
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({"font.size": 11, "figure.facecolor": "white"})
rt = 8.314462618 * 300
# Values are J/mol; normalized rates k/nu are dimensionless.
barriers = np.array([[80000, 100000], [50000, 70000]], dtype=float)
logs = -barriers / (rt * math.log(10))
speedup = math.exp(30000 / rt)
equilibrium = math.exp(20000 / rt)
colors = ("#b64928", "#176d9c")
fig, (ax, ratio_ax) = plt.subplots(1, 2, figsize=(8, 4.6), dpi=120,
gridspec_kw={"width_ratios": [1.35, 1]})
x = np.arange(2)
for row, color, label, offset in zip(
logs, colors, ("Without catalyst", "With catalyst"), (-0.18, 0.18)
):
bars = ax.bar(x + offset, row, width=0.34, color=color, label=label)
for bar, value in zip(bars, row):
ax.text(bar.get_x() + bar.get_width() / 2, value - 0.5,
f"{value:.2f}", ha="center", va="top", fontsize=10)
ax.set_xticks(x, ("Forward", "Reverse"))
ax.set(ylim=(-20, 0), ylabel=r"$\log_{10}(k/\nu)$",
title="Faster in both directions")
ax.grid(axis="y", alpha=0.18)
ax.set_axisbelow(True)
ax.text(0.5, -0.30, f"Each direction × {speedup / 1e5:.3f} × 10⁵",
transform=ax.transAxes, ha="center", fontsize=10)
ratio_logs = logs[:, 0] - logs[:, 1]
bars = ratio_ax.bar(x, ratio_logs, color=colors, width=0.55)
for bar, value in zip(bars, ratio_logs):
ratio_ax.text(bar.get_x() + bar.get_width() / 2, value + 0.09,
f"{value:.3f}", ha="center", fontsize=10)
ratio_ax.set_xticks(x, ("Without\ncatalyst", "With\ncatalyst"))
ratio_ax.set(ylim=(0, 4.5), ylabel=r"$\log_{10}(k_f/k_r)$",
title="Same equilibrium ratio")
ratio_ax.grid(axis="y", alpha=0.18)
ratio_ax.set_axisbelow(True)
ratio_ax.text(0.5, -0.30, f"Both routes: K = {equilibrium:.2f}",
transform=ratio_ax.transAxes, ha="center", fontsize=10)
for panel in (ax, ratio_ax):
panel.spines[["top", "right"]].set_visible(False)
fig.suptitle("Rate comparisons at 300 K", weight="bold", y=0.96)
fig.text(0.5, 0.88, "Chosen free-energy barriers; common ν = kBT/h",
ha="center", fontsize=10)
fig.legend(handles=ax.get_legend_handles_labels()[0],
labels=ax.get_legend_handles_labels()[1], loc="lower center",
ncol=2, frameon=False, bbox_to_anchor=(0.5, 0.015), fontsize=10)
fig.subplots_adjust(left=0.09, right=0.98, wspace=0.43, top=0.74, bottom=0.29)
fig.savefig("catalyst-forward-reverse-rate-ratios.png", facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()