{"spec_id":"line-arrhenius","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-arrhenius: Arrhenius Plot for Reaction Kinetics\nLibrary: matplotlib 3.11.0 | Python 3.13.14\nQuality: 90/100 | Updated: 2026-06-24\n\"\"\"\n\nimport os\n\nimport matplotlib.patheffects as pe\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as ticker\nimport numpy as np\nfrom matplotlib.colors import LinearSegmentedColormap\n\n\n# Theme tokens\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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint sequential colormap for continuous temperature data (#009E73 → #4467A3)\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\n\n# Data — first-order decomposition reaction rate constants at various temperatures\ntemperature_K = np.array([300, 350, 400, 450, 500, 550, 600])\nactivation_energy_true = 75000  # J/mol (75 kJ/mol)\nR_gas = 8.314  # J/(mol·K)\npre_exponential = 1e13  # s⁻¹\n\nnp.random.seed(42)\nrate_constant_k = (\n    pre_exponential\n    * np.exp(-activation_energy_true / (R_gas * temperature_K))\n    * np.exp(np.random.normal(0, 0.15, len(temperature_K)))\n)\n\ninv_temperature = 1000 / temperature_K  # 1000/T for cleaner x-axis values\nln_k = np.log(rate_constant_k)\n\n# Linear regression\ncoeffs = np.polyfit(1 / temperature_K, ln_k, 1)\nslope, intercept = coeffs\nln_k_predicted = slope * (1 / temperature_K) + intercept\nss_res = np.sum((ln_k - ln_k_predicted) ** 2)\nss_tot = np.sum((ln_k - np.mean(ln_k)) ** 2)\nr_squared = 1 - ss_res / ss_tot\nactivation_energy = -slope * R_gas / 1000  # kJ/mol\n\ninv_temp_fit = np.linspace(1 / temperature_K.max(), 1 / temperature_K.min(), 200)\nln_k_fit = slope * inv_temp_fit + intercept\n\n# Confidence band (±2 SE)\nresidual_se = np.sqrt(ss_res / (len(temperature_K) - 2))\ninv_T_arr = 1 / temperature_K\nx_mean = np.mean(inv_T_arr)\ns_xx = np.sum((inv_T_arr - x_mean) ** 2)\nse_fit = residual_se * np.sqrt(1 / len(inv_T_arr) + (inv_temp_fit - x_mean) ** 2 / s_xx)\n\n# Plot — figsize=(8,4.5) dpi=400 → exactly 3200×1800 px\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG, constrained_layout=True)\nax.set_facecolor(PAGE_BG)\n\n# 95% confidence band\nax.fill_between(\n    inv_temp_fit * 1000,\n    ln_k_fit - 2 * se_fit,\n    ln_k_fit + 2 * se_fit,\n    color=INK_SOFT,\n    alpha=0.12,\n    zorder=1,\n    label=\"95% confidence band\",\n)\n\n# Regression line (Imprint blue #4467A3)\nax.plot(\n    inv_temp_fit * 1000,\n    ln_k_fit,\n    color=\"#4467A3\",\n    linewidth=2.5,\n    alpha=0.90,\n    label=\"Linear fit\",\n    zorder=2,\n    path_effects=[pe.withStroke(linewidth=4, foreground=PAGE_BG, alpha=0.5)],\n)\n\n# Data points — Imprint sequential colormap by temperature\nscatter = ax.scatter(\n    inv_temperature,\n    ln_k,\n    s=180,\n    c=temperature_K,\n    cmap=imprint_seq,\n    vmin=temperature_K.min(),\n    vmax=temperature_K.max(),\n    edgecolors=PAGE_BG,\n    linewidth=1.5,\n    zorder=4,\n    label=\"Experimental data\",\n)\n\n# Colorbar — temperature scale\ncbar = fig.colorbar(scatter, ax=ax, pad=0.02, aspect=25, shrink=0.80)\ncbar.set_label(\"Temperature (K)\", fontsize=8, labelpad=8, color=INK_SOFT)\ncbar.ax.tick_params(labelsize=7, colors=INK_SOFT)\ncbar.outline.set_visible(False)\n\n# Annotation — Ea and R²\nmid_idx = len(inv_temp_fit) // 3\nax.annotate(\n    f\"$E_a$ = {activation_energy:.1f} kJ/mol\\n$R^2$ = {r_squared:.4f}\",\n    xy=(inv_temp_fit[mid_idx] * 1000, ln_k_fit[mid_idx]),\n    xytext=(35, 45),\n    textcoords=\"offset points\",\n    fontsize=8,\n    fontweight=\"medium\",\n    color=INK,\n    bbox={\n        \"boxstyle\": \"round,pad=0.4\",\n        \"facecolor\": ELEVATED_BG,\n        \"edgecolor\": \"#4467A3\",\n        \"alpha\": 0.95,\n        \"linewidth\": 1.2,\n    },\n    arrowprops={\"arrowstyle\": \"-|>\", \"color\": \"#4467A3\", \"lw\": 1.5, \"connectionstyle\": \"arc3,rad=0.15\"},\n)\n\n# Style\ntitle = \"line-arrhenius · python · matplotlib · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * 67 / len(title))) if len(title) > 67 else 12\n\nax.set_xlabel(\"1000 / T  (K⁻¹)\", fontsize=10, labelpad=8, color=INK)\nax.set_ylabel(\"ln(k)\", fontsize=10, labelpad=8, color=INK)\nax.set_title(\n    title,\n    fontsize=title_fontsize,\n    fontweight=\"medium\",\n    pad=10,\n    color=INK,\n    path_effects=[pe.withStroke(linewidth=3, foreground=PAGE_BG, alpha=0.8)],\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)\nax.spines[\"left\"].set_linewidth(0.7)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_linewidth(0.7)\nax.spines[\"bottom\"].set_color(INK_SOFT)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.6, color=INK)\nax.xaxis.grid(True, alpha=0.08, linewidth=0.4, color=INK)\nax.xaxis.set_major_formatter(ticker.FormatStrFormatter(\"%.1f\"))\n\n# Legend\nleg = ax.legend(fontsize=7, framealpha=0.95, edgecolor=INK_SOFT, loc=\"upper right\", fancybox=False)\nif leg:\n    leg.get_frame().set_facecolor(ELEVATED_BG)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n\n# Secondary x-axis — temperature in K\nax2 = ax.twiny()\nax2.set_xlim(ax.get_xlim())\ntemp_ticks = np.array([600, 550, 500, 450, 400, 350, 300])\ntick_positions = 1000 / temp_ticks\nax2.set_xticks(tick_positions)\nax2.set_xticklabels([f\"{t} K\" for t in temp_ticks], fontsize=7)\nax2.set_xlabel(\"Temperature (K)\", fontsize=9, labelpad=10, color=INK)\nax2.spines[\"right\"].set_visible(False)\nax2.spines[\"top\"].set_linewidth(0.7)\nax2.spines[\"top\"].set_color(INK_SOFT)\nax2.tick_params(axis=\"x\", labelsize=7, colors=INK_SOFT, labelcolor=INK_SOFT)\n\n# Save — no bbox_inches so figsize×dpi → exactly 3200×1800\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}