{"spec_id":"feynman-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nfeynman-basic: Feynman Diagram for Particle Interactions\nLibrary: letsplot 4.10.1 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-06-03\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    arrow,\n    coord_fixed,\n    element_rect,\n    element_text,\n    geom_label,\n    geom_path,\n    geom_point,\n    geom_segment,\n    geom_text,\n    ggplot,\n    ggsave,\n    ggsize,\n    labs,\n    layer_tooltips,\n    scale_color_identity,\n    scale_fill_identity,\n    theme,\n    theme_void,\n    xlim,\n    ylim,\n)\n\n\nLetsPlot.setup_html()\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\"\n\n# Imprint palette — particle type colors (canonical order, first series = brand green)\nFERMION_COLOR = \"#009E73\"  # brand green — fermions (e-, e+, q, q̄)\nBOSON_COLOR = \"#C475FD\"  # lavender — Z* boson (dashed propagator, key mediator)\nGLUON_COLOR = \"#4467A3\"  # blue — gluon (curly bremsstrahlung)\nPHOTON_COLOR = \"#BD8233\"  # ochre — photon γ (wavy, shown in legend)\n\n# Diagram: e+e- → Z* → qq̄g  (QED+QCD: annihilation, Z-mediated pair creation, gluon emission)\nv1x, v1y = 0.28, 0.50  # V1: e+e- annihilation vertex\nv2x, v2y = 0.58, 0.50  # V2: qq̄ pair creation vertex\nv3x, v3y = 0.76, 0.63  # V3: gluon bremsstrahlung vertex\next = 0.20  # external leg length\n\n# Fermion segments (arrow convention: particle → vertex, antiparticle ← vertex)\n# e-: arrow at V1 (electron arrives); e+: arrow at lower-left (positron arrow reversal)\n# q: arrows away from V2/V3; q̄: arrow toward V2 (antiquark fermion-flow reversal)\nfermion_df = pd.DataFrame(\n    {\n        \"x\": [0.06, v1x, v2x, v3x, 0.95],\n        \"y\": [v1y + ext, v1y, v2y, v3y, v1y - ext],\n        \"xend\": [v1x, 0.06, v3x, 0.95, v2x],\n        \"yend\": [v1y, v1y - ext, v3y, v3y + 0.14, v2y],\n        \"particle\": [\"e⁻ (electron)\", \"e⁺ (positron)\", \"q (up quark)\", \"q (up quark cont.)\", \"q̅ (down antiquark)\"],\n    }\n)\nfermion_df[\"color\"] = FERMION_COLOR\n\n# Z* boson propagator — the key interaction mediator (emphasized: thicker, dashed)\nboson_df = pd.DataFrame({\"x\": [v1x], \"xend\": [v2x], \"y\": [v1y], \"yend\": [v2y]})\n\n# Gluon bremsstrahlung: V3 → lower-right (curly/looped via geom_path)\nt_g = np.linspace(0, 1, 600)\ngluon_dx, gluon_dy = 0.19, -0.21\ngluon_df = pd.DataFrame(\n    {\n        \"x\": v3x + t_g * gluon_dx + 0.011 * np.sin(t_g * 10 * 2 * np.pi),\n        \"y\": v3y + t_g * gluon_dy + 0.019 * np.sin(t_g * 10 * 2 * np.pi + np.pi / 2),\n        \"grp\": 1,\n    }\n)\n\n# Vertex dots (interactive tooltips in HTML export)\nvertex_df = pd.DataFrame(\n    {\n        \"x\": [v1x, v2x, v3x],\n        \"y\": [v1y, v2y, v3y],\n        \"vertex\": [\"V₁: e⁻e⁺ annihilation\", \"V₂: qq̅ pair creation\", \"V₃: gluon emission\"],\n    }\n)\n\n# Particle endpoint labels\nlabels_df = pd.DataFrame(\n    {\n        \"x\": [0.03, 0.03, (v1x + v2x) / 2, 0.97, 0.97, 0.97],\n        \"y\": [v1y + ext + 0.02, v1y - ext - 0.02, v1y + 0.065, v3y + 0.15, v3y + gluon_dy + 0.06, v1y - ext - 0.02],\n        \"label\": [\"e⁻\", \"e⁺\", \"Z*\", \"q\", \"g\", \"q̅\"],\n        \"fill\": [ELEVATED_BG] * 6,\n    }\n)\n\n# Time axis\ntime_df = pd.DataFrame({\"x\": [0.23], \"xend\": [0.63], \"y\": [0.10], \"yend\": [0.10]})\ntime_lbl = pd.DataFrame({\"x\": [0.43], \"y\": [0.055], \"label\": [\"time\"]})\n\n# Legend (consolidated: one DataFrame per line type, one text DataFrame)\nleg_x0, leg_len = 0.09, 0.065\nleg_top, leg_dy = 0.97, 0.054\n\nleg_fermion = pd.DataFrame({\"x\": [leg_x0], \"xend\": [leg_x0 + leg_len], \"y\": [leg_top], \"yend\": [leg_top]})\nleg_boson_seg = pd.DataFrame(\n    {\"x\": [leg_x0], \"xend\": [leg_x0 + leg_len], \"y\": [leg_top - leg_dy], \"yend\": [leg_top - leg_dy]}\n)\n\nt_lp = np.linspace(0, 1, 200)\nleg_photon = pd.DataFrame(\n    {\"x\": leg_x0 + t_lp * leg_len, \"y\": (leg_top - 2 * leg_dy) + 0.009 * np.sin(t_lp * 5 * 2 * np.pi), \"grp\": 1}\n)\n\nt_lg = np.linspace(0, 1, 300)\nleg_gluon = pd.DataFrame(\n    {\n        \"x\": leg_x0 + t_lg * leg_len + 0.004 * np.sin(t_lg * 9 * 2 * np.pi),\n        \"y\": (leg_top - 3 * leg_dy) + 0.009 * np.sin(t_lg * 9 * 2 * np.pi + np.pi / 2),\n        \"grp\": 1,\n    }\n)\n\nleg_text = pd.DataFrame(\n    {\n        \"x\": [leg_x0 + leg_len + 0.013] * 4,\n        \"y\": [leg_top - i * leg_dy for i in range(4)],\n        \"label\": [\"Fermion\", \"Boson (Z*)\", \"Photon (γ)\", \"Gluon (g)\"],\n    }\n)\n\n# Reaction equation — data storytelling focal point (bold, right of legend)\neq_df = pd.DataFrame({\"x\": [0.57], \"y\": [0.975], \"label\": [\"e⁻e⁺ → Z* → qq̅g\"]})\n\ntitle = \"feynman-basic · python · letsplot · anyplot.ai\"\n\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    plot_title=element_text(size=13, color=INK_SOFT),\n    plot_margin=[20, 15, 15, 15],\n    legend_position=\"none\",\n)\n\nplot = (\n    ggplot()\n    + theme_void()\n    # Z* boson: the key mediator — emphasized with thicker dashed line\n    + geom_segment(\n        data=boson_df,\n        mapping=aes(x=\"x\", y=\"y\", xend=\"xend\", yend=\"yend\"),\n        size=3.8,\n        color=BOSON_COLOR,\n        linetype=\"dashed\",\n    )\n    # Fermion lines with direction arrows (lets-plot distinctive: native arrow())\n    + geom_segment(\n        data=fermion_df,\n        mapping=aes(x=\"x\", y=\"y\", xend=\"xend\", yend=\"yend\", color=\"color\"),\n        size=2.5,\n        arrow=arrow(angle=20, length=10, type=\"closed\"),\n        tooltips=layer_tooltips().line(\"@particle\"),\n    )\n    + scale_color_identity()\n    # Gluon bremsstrahlung (curly loops via geom_path)\n    + geom_path(data=gluon_df, mapping=aes(x=\"x\", y=\"y\", group=\"grp\"), size=2.5, color=GLUON_COLOR)\n    # Vertex dots with interactive hover (lets-plot distinctive: layer_tooltips)\n    + geom_point(\n        data=vertex_df,\n        mapping=aes(x=\"x\", y=\"y\"),\n        size=10,\n        color=INK,\n        shape=16,\n        tooltips=layer_tooltips().line(\"@vertex\"),\n    )\n    # Particle labels with rounded backgrounds (lets-plot distinctive: geom_label)\n    + geom_label(\n        data=labels_df,\n        mapping=aes(x=\"x\", y=\"y\", label=\"label\", fill=\"fill\"),\n        size=22,\n        color=INK_SOFT,\n        fontface=\"italic\",\n        label_padding=0.2,\n        label_r=0.15,\n        label_size=0.3,\n        alpha=0.92,\n    )\n    + scale_fill_identity()\n    # Time axis arrow\n    + geom_segment(\n        data=time_df,\n        mapping=aes(x=\"x\", y=\"y\", xend=\"xend\", yend=\"yend\"),\n        size=0.8,\n        color=INK_SOFT,\n        arrow=arrow(angle=20, length=7, type=\"open\"),\n    )\n    + geom_text(data=time_lbl, mapping=aes(x=\"x\", y=\"y\", label=\"label\"), size=10, color=INK_SOFT, fontface=\"italic\")\n    # Legend\n    + geom_segment(\n        data=leg_fermion,\n        mapping=aes(x=\"x\", y=\"y\", xend=\"xend\", yend=\"yend\"),\n        size=1.8,\n        color=FERMION_COLOR,\n        arrow=arrow(angle=20, length=6, type=\"closed\"),\n    )\n    + geom_segment(\n        data=leg_boson_seg,\n        mapping=aes(x=\"x\", y=\"y\", xend=\"xend\", yend=\"yend\"),\n        size=1.8,\n        color=BOSON_COLOR,\n        linetype=\"dashed\",\n    )\n    + geom_path(data=leg_photon, mapping=aes(x=\"x\", y=\"y\", group=\"grp\"), size=1.8, color=PHOTON_COLOR)\n    + geom_path(data=leg_gluon, mapping=aes(x=\"x\", y=\"y\", group=\"grp\"), size=1.8, color=GLUON_COLOR)\n    + geom_text(data=leg_text, mapping=aes(x=\"x\", y=\"y\", label=\"label\"), size=10, color=INK_SOFT, hjust=0)\n    # Reaction equation — bold focal point showing the full QED+QCD process\n    + geom_text(data=eq_df, mapping=aes(x=\"x\", y=\"y\", label=\"label\"), size=13, color=INK, fontface=\"bold\")\n    + coord_fixed(ratio=0.5625)\n    + xlim(-0.02, 1.08)\n    + ylim(0.02, 1.05)\n    + labs(title=title)\n    + anyplot_theme\n    + ggsize(800, 450)\n)\n\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=4)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}