{"spec_id":"feynman-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nfeynman-basic: Feynman Diagram for Particle Interactions\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-06-03\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove this directory from sys.path to prevent local matplotlib.py from\n# shadowing the installed package (implementations dir contains other lib files)\n_here = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))\nsys.path = [p for p in sys.path if os.path.realpath(p if p else os.getcwd()) != _here]\n\nimport matplotlib.patches as mpatches\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\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 palette — canonical order, first series always #009E73\nFERMION = \"#009E73\"  # Imprint position 1 (brand green) — electrons\nPHOTON = \"#C475FD\"  # Imprint position 2 (lavender)    — photons\nGLUON = \"#4467A3\"  # Imprint position 3 (blue)         — gluons (reference only)\nSCALAR = \"#BD8233\"  # Imprint position 4 (ochre)        — scalar bosons (reference only)\n\nIMPRINT_PALETTE = [FERMION, PHOTON, GLUON, SCALAR, \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\"]\nsns.set_theme(style=\"white\", rc={\"figure.facecolor\": PAGE_BG, \"axes.facecolor\": PAGE_BG, \"text.color\": INK})\nsns.set_palette(IMPRINT_PALETTE)\n\n# Canvas — landscape 3200 × 1800 px\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# === Main Diagram: Compton Scattering (e⁻ + γ → e⁻ + γ) ===\n# t-channel: incoming electron absorbs the photon (v1), propagates as a virtual\n# electron, then emits the scattered photon at v2\nv1 = np.array([0.30, 0.58])  # absorption vertex\nv2 = np.array([0.70, 0.58])  # emission vertex\n\ne_in = np.array([0.05, 0.90])  # incoming electron endpoint\ne_out = np.array([0.95, 0.90])  # outgoing electron endpoint\ng_in = np.array([0.05, 0.22])  # incoming photon endpoint\ng_out = np.array([0.95, 0.22])  # outgoing photon endpoint\n\narrow_kw = {\"arrowstyle\": \"-|>\", \"color\": FERMION, \"lw\": 2.5, \"mutation_scale\": 18}\n\n# Fermion lines with directional arrows\nax.annotate(\"\", xy=v1, xytext=e_in, arrowprops=arrow_kw)  # e⁻(in) → v1\nax.annotate(\"\", xy=v2, xytext=v1, arrowprops=arrow_kw)  # v1 → v2 (virtual e⁻)\nax.annotate(\"\", xy=e_out, xytext=v2, arrowprops=arrow_kw)  # v2 → e⁻(out)\n\n# Incoming photon wavy line\nt = np.linspace(0, 1, 400)\nd_gin = v1 - g_in\nperp_gin = np.array([-d_gin[1], d_gin[0]]) / np.linalg.norm(d_gin)\nwave_gin = 0.018 * np.sin(2 * np.pi * 7 * t)\ngamma_in_df = pd.DataFrame(\n    {\"x\": g_in[0] + t * d_gin[0] + wave_gin * perp_gin[0], \"y\": g_in[1] + t * d_gin[1] + wave_gin * perp_gin[1]}\n)\nsns.lineplot(data=gamma_in_df, x=\"x\", y=\"y\", ax=ax, color=PHOTON, linewidth=2.5, sort=False, legend=False)\n\n# Outgoing photon wavy line\nd_gout = g_out - v2\nperp_gout = np.array([-d_gout[1], d_gout[0]]) / np.linalg.norm(d_gout)\nwave_gout = 0.018 * np.sin(2 * np.pi * 7 * t)\ngamma_out_df = pd.DataFrame(\n    {\"x\": v2[0] + t * d_gout[0] + wave_gout * perp_gout[0], \"y\": v2[1] + t * d_gout[1] + wave_gout * perp_gout[1]}\n)\nsns.lineplot(data=gamma_out_df, x=\"x\", y=\"y\", ax=ax, color=PHOTON, linewidth=2.5, sort=False, legend=False)\n\n# Interaction vertex dots\nvertex_df = pd.DataFrame({\"x\": [v1[0], v2[0]], \"y\": [v1[1], v2[1]]})\nsns.scatterplot(data=vertex_df, x=\"x\", y=\"y\", ax=ax, color=FERMION, s=100, zorder=5, legend=False)\n\n# Particle labels\nlkw_e = {\"fontsize\": 10, \"fontweight\": \"bold\", \"ha\": \"center\", \"va\": \"center\", \"color\": FERMION}\nlkw_g = {\"fontsize\": 10, \"fontweight\": \"bold\", \"ha\": \"center\", \"va\": \"center\", \"color\": PHOTON}\nax.text(e_in[0] - 0.04, e_in[1] + 0.04, r\"$e^-$\", **lkw_e)\nax.text(e_out[0] + 0.04, e_out[1] + 0.04, r\"$e^-$\", **lkw_e)\nax.text(g_in[0] - 0.04, g_in[1] - 0.04, r\"$\\gamma$\", **lkw_g)\nax.text(g_out[0] + 0.04, g_out[1] - 0.04, r\"$\\gamma$\", **lkw_g)\nax.text(0.50, 0.63, r\"$e^-$ (virtual)\", fontsize=8, color=FERMION, ha=\"center\", va=\"bottom\", style=\"italic\")\n\n# Time arrow\nax.annotate(\n    \"\",\n    xy=(0.90, 0.12),\n    xytext=(0.10, 0.12),\n    arrowprops={\"arrowstyle\": \"-|>\", \"color\": INK_MUTED, \"lw\": 1.5, \"mutation_scale\": 12},\n)\nax.text(0.50, 0.08, \"time\", fontsize=8, color=INK_MUTED, ha=\"center\", style=\"italic\")\n\n# Separator between main diagram and reference legend\nax.plot([0.03, 0.97], [0.03, 0.03], color=INK_SOFT, lw=0.5, alpha=0.4)\n\n# Elevated card background for reference legend (visual separation)\nlegend_card = mpatches.FancyBboxPatch(\n    (0.01, -0.21),\n    0.98,\n    0.23,\n    boxstyle=\"round,pad=0.0\",\n    facecolor=ELEVATED_BG,\n    edgecolor=INK_SOFT,\n    linewidth=0.5,\n    alpha=1.0,\n    transform=ax.transData,\n    zorder=0.5,\n)\nax.add_patch(legend_card)\n\n# === Reference legend: all 4 particle line styles ===\nref_y = -0.07\nref_spans = [(0.05, 0.18), (0.30, 0.43), (0.55, 0.68), (0.80, 0.93)]\nref_names = [\"Fermion\\n(solid + arrow)\", \"Photon\\n(wavy)\", \"Gluon\\n(curly)\", \"Scalar Boson\\n(dashed)\"]\nref_cols = [FERMION, PHOTON, GLUON, SCALAR]\n\n# Fermion reference\nax.annotate(\n    \"\",\n    xy=(ref_spans[0][1], ref_y),\n    xytext=(ref_spans[0][0], ref_y),\n    arrowprops={\"arrowstyle\": \"-|>\", \"color\": FERMION, \"lw\": 2.5, \"mutation_scale\": 15},\n)\n\n# Photon reference — wavy\ntr = np.linspace(0, 1, 300)\nxs0, xs1 = ref_spans[1]\nphoton_ref = pd.DataFrame({\"x\": xs0 + tr * (xs1 - xs0), \"y\": ref_y + 0.018 * np.sin(2 * np.pi * 4 * tr)})\nsns.lineplot(data=photon_ref, x=\"x\", y=\"y\", ax=ax, color=PHOTON, linewidth=2.5, sort=False, legend=False)\n\n# Gluon reference — curly (cycloid parameterization)\ntg = np.linspace(0, 1, 1000)\nxs0, xs1 = ref_spans[2]\nspan_g = xs1 - xs0\nn_coils = 4\nr_coil = span_g / (2 * np.pi * n_coils) * 4.0\nphase_g = 2 * np.pi * n_coils * tg\ngluon_ref = pd.DataFrame(\n    {\"x\": xs0 + tg * span_g + r_coil * np.sin(phase_g), \"y\": ref_y + r_coil * (1 - np.cos(phase_g))}\n)\nsns.lineplot(data=gluon_ref, x=\"x\", y=\"y\", ax=ax, color=GLUON, linewidth=2.5, sort=False, legend=False)\n\n# Scalar boson reference — dashed\nxs0, xs1 = ref_spans[3]\nboson_ref = pd.DataFrame({\"x\": [xs0, xs1], \"y\": [ref_y, ref_y]})\nsns.lineplot(data=boson_ref, x=\"x\", y=\"y\", ax=ax, color=SCALAR, linewidth=2.5, linestyle=\"--\", legend=False)\n\n# Reference labels below each style\nfor (xs0, xs1), name, col in zip(ref_spans, ref_names, ref_cols, strict=False):\n    ax.text((xs0 + xs1) / 2, ref_y - 0.05, name, fontsize=8, ha=\"center\", va=\"top\", color=col, fontweight=\"bold\")\n\n# Title — 66 chars, within 67-char baseline so no scaling needed\ntitle = \"Compton Scattering · feynman-basic · python · seaborn · anyplot.ai\"\nax.set_title(title, fontsize=12, fontweight=\"medium\", color=INK, pad=12)\nax.set_xlim(-0.05, 1.05)\nax.set_ylim(-0.24, 1.02)\nax.axis(\"off\")\nsns.despine(ax=ax, left=True, bottom=True)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}