{"spec_id":"feynman-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nfeynman-basic: Feynman Diagram for Particle Interactions\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-06-03\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\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 — particle type colors\n# Semantic exception: fermion lines use #4467A3 (Imprint blue) rather than #009E73.\n# Blue = universally established color for electron/fermion lines in Feynman diagram\n# tools (FeynCalc, JaxoDraw, TikZ-Feynman) — a recognized physics-domain convention\n# analogous to financial red/green. Z boson (vector) takes #009E73 as second series.\nCOLORS = {\n    \"fermion\": \"#4467A3\",  # Imprint blue — electrons / muons (physics convention)\n    \"vector\": \"#009E73\",  # Imprint green — Z boson (vector, wavy)\n    \"photon\": \"#AE3030\",  # Imprint matte red — photons (wavy)\n    \"boson\": \"#C475FD\",  # Imprint lavender — Higgs scalar (dashed)\n}\nLINE_W = 4\n\n# Data — Higgs-strahlung: e+e- → Z* → ZH → μ+μ- γγ (lepton collider)\n# Showcases all 4 line types: fermion (straight + arrow), vector Z (wavy),\n# photon (wavy), scalar H (dashed)\nvertices = {\n    \"v1\": (0.18, 0.50),  # e+e- annihilation → Z*\n    \"v2\": (0.50, 0.50),  # Z* → ZH production\n    \"v3\": (0.82, 0.78),  # Z → μ+μ- decay\n    \"v4\": (0.78, 0.22),  # H → γγ decay\n}\n\npropagators = [\n    {\"from\": (0.0, 0.72), \"to\": \"v1\", \"type\": \"fermion\", \"label\": \"e⁻\"},\n    {\"from\": (0.0, 0.28), \"to\": \"v1\", \"type\": \"fermion\", \"label\": \"e⁺\", \"anti\": True},\n    {\"from\": \"v1\", \"to\": \"v2\", \"type\": \"vector\", \"label\": \"Z*\"},\n    {\"from\": \"v2\", \"to\": \"v3\", \"type\": \"vector\", \"label\": \"Z\"},\n    {\"from\": \"v2\", \"to\": \"v4\", \"type\": \"boson\", \"label\": \"H\"},\n    {\"from\": \"v3\", \"to\": (1.0, 0.96), \"type\": \"fermion\", \"label\": \"μ⁻\"},\n    {\"from\": \"v3\", \"to\": (1.0, 0.60), \"type\": \"fermion\", \"label\": \"μ⁺\", \"anti\": True},\n    {\"from\": \"v4\", \"to\": (1.0, 0.38), \"type\": \"photon\", \"label\": \"γ\"},\n    {\"from\": \"v4\", \"to\": (1.0, 0.04), \"type\": \"photon\", \"label\": \"γ\"},\n]\n\n# Label offsets (dx, dy) from propagator midpoint\nlabel_offsets = [\n    (-0.04, 0.06),  # e⁻\n    (-0.04, -0.06),  # e⁺\n    (0.00, 0.07),  # Z*\n    (0.00, 0.07),  # Z\n    (0.00, -0.07),  # H\n    (-0.04, 0.05),  # μ⁻\n    (-0.04, -0.05),  # μ⁺\n    (-0.04, 0.05),  # γ upper\n    (-0.04, -0.05),  # γ lower\n]\n\nfig = go.Figure()\n\nfor i, prop in enumerate(propagators):\n    p0 = vertices[prop[\"from\"]] if isinstance(prop[\"from\"], str) else prop[\"from\"]\n    p1 = vertices[prop[\"to\"]] if isinstance(prop[\"to\"], str) else prop[\"to\"]\n    color = COLORS[prop[\"type\"]]\n    dx, dy = p1[0] - p0[0], p1[1] - p0[1]\n    length = np.sqrt(dx**2 + dy**2)\n    ptype = prop[\"type\"]\n\n    if ptype == \"fermion\":\n        fig.add_trace(\n            go.Scatter(\n                x=[p0[0], p1[0]],\n                y=[p0[1], p1[1]],\n                mode=\"lines\",\n                line={\"color\": color, \"width\": LINE_W},\n                showlegend=False,\n                hovertemplate=f\"<b>{prop['label']}</b><extra></extra>\",\n            )\n        )\n        mx, my = (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2\n        ndx, ndy = dx / length, dy / length\n        if prop.get(\"anti\"):\n            ndx, ndy = -ndx, -ndy  # antiparticle: arrow reversed\n        fig.add_annotation(\n            x=mx + 0.018 * ndx,\n            y=my + 0.018 * ndy,\n            ax=mx - 0.05 * ndx,\n            ay=my - 0.05 * ndy,\n            xref=\"x\",\n            yref=\"y\",\n            axref=\"x\",\n            ayref=\"y\",\n            showarrow=True,\n            arrowhead=3,\n            arrowsize=2.5,\n            arrowwidth=3.5,\n            arrowcolor=color,\n            text=\"\",\n        )\n\n    elif ptype in (\"photon\", \"vector\"):\n        t = np.linspace(0, 1, 400)\n        perp_x, perp_y = -dy / length, dx / length\n        amp = 0.030\n        freq = 10 if ptype == \"photon\" else 7  # Z slightly fewer oscillations\n        taper = np.minimum(t / 0.07, 1.0) * np.minimum((1 - t) / 0.07, 1.0)\n        wave = amp * np.sin(2 * np.pi * freq * t) * taper\n        fig.add_trace(\n            go.Scatter(\n                x=p0[0] + t * dx + wave * perp_x,\n                y=p0[1] + t * dy + wave * perp_y,\n                mode=\"lines\",\n                line={\"color\": color, \"width\": LINE_W},\n                showlegend=False,\n                hovertemplate=f\"<b>{prop['label']}</b><extra></extra>\",\n            )\n        )\n\n    elif ptype == \"boson\":\n        fig.add_trace(\n            go.Scatter(\n                x=[p0[0], p1[0]],\n                y=[p0[1], p1[1]],\n                mode=\"lines\",\n                line={\"color\": color, \"width\": LINE_W, \"dash\": \"10px,6px\"},\n                showlegend=False,\n                hovertemplate=f\"<b>{prop['label']}</b><extra></extra>\",\n            )\n        )\n\n    # Particle label at propagator midpoint + offset\n    lx = (p0[0] + p1[0]) / 2 + label_offsets[i][0]\n    ly = (p0[1] + p1[1]) / 2 + label_offsets[i][1]\n    fig.add_annotation(\n        x=lx,\n        y=ly,\n        text=f\"<b>{prop['label']}</b>\",\n        showarrow=False,\n        font={\"size\": 22, \"color\": color, \"family\": \"serif\"},\n        xanchor=\"center\",\n        yanchor=\"middle\",\n    )\n\n# Vertex dots (theme-adaptive ink color)\nfor name, (vx, vy) in vertices.items():\n    fig.add_trace(\n        go.Scatter(\n            x=[vx],\n            y=[vy],\n            mode=\"markers\",\n            marker={\"size\": 16, \"color\": INK, \"line\": {\"width\": 2.5, \"color\": PAGE_BG}},\n            showlegend=False,\n            hovertemplate=f\"<b>Vertex {name}</b><br>Interaction point<extra></extra>\",\n        )\n    )\n\n# Legend — 4 particle types with miniature line samples, horizontal row at bottom\nleg_items = [\n    (\"fermion\", \"Fermion (straight)\"),\n    (\"vector\", \"Z boson (wavy)\"),\n    (\"photon\", \"Photon (wavy)\"),\n    (\"boson\", \"Higgs (dashed)\"),\n]\nlegend_ts = np.linspace(0, 1, 200)\nlegend_taper = np.minimum(legend_ts / 0.1, 1.0) * np.minimum((1 - legend_ts) / 0.1, 1.0)\nlw_len = 0.060\nx_starts = [0.04, 0.27, 0.52, 0.75]\ny_leg = -0.065\n\nfor j, (ptype, desc) in enumerate(leg_items):\n    lx = x_starts[j]\n    ly = y_leg\n    col = COLORS[ptype]\n\n    if ptype == \"fermion\":\n        fig.add_shape(type=\"line\", x0=lx, y0=ly, x1=lx + lw_len, y1=ly, line={\"color\": col, \"width\": 3})\n        fig.add_annotation(\n            x=lx + lw_len * 0.62,\n            y=ly,\n            ax=lx + lw_len * 0.38,\n            ay=ly,\n            xref=\"x\",\n            yref=\"y\",\n            axref=\"x\",\n            ayref=\"y\",\n            showarrow=True,\n            arrowhead=3,\n            arrowsize=1.8,\n            arrowwidth=2.5,\n            arrowcolor=col,\n            text=\"\",\n        )\n    elif ptype == \"boson\":\n        fig.add_shape(\n            type=\"line\", x0=lx, y0=ly, x1=lx + lw_len, y1=ly, line={\"color\": col, \"width\": 3, \"dash\": \"10px,6px\"}\n        )\n    else:\n        freq_leg = 5 if ptype == \"photon\" else 4\n        theta_s = 2 * np.pi * freq_leg * legend_ts\n        px = lx + legend_ts * lw_len\n        py = ly + 0.011 * np.sin(theta_s) * legend_taper\n        fig.add_trace(\n            go.Scatter(x=px, y=py, mode=\"lines\", line={\"color\": col, \"width\": 2.5}, showlegend=False, hoverinfo=\"skip\")\n        )\n\n    fig.add_annotation(\n        x=lx + lw_len + 0.010,\n        y=ly,\n        text=desc,\n        showarrow=False,\n        font={\"size\": 14, \"color\": col},\n        xanchor=\"left\",\n        yanchor=\"middle\",\n    )\n\n# Time axis arrow (bottom of diagram)\nfig.add_annotation(\n    x=0.68,\n    y=-0.12,\n    ax=0.04,\n    ay=-0.12,\n    xref=\"x\",\n    yref=\"y\",\n    axref=\"x\",\n    ayref=\"y\",\n    showarrow=True,\n    arrowhead=2,\n    arrowsize=2,\n    arrowwidth=2,\n    arrowcolor=INK_MUTED,\n    text=\"\",\n)\nfig.add_annotation(\n    x=0.36, y=-0.145, text=\"<i>time</i>\", showarrow=False, font={\"size\": 18, \"color\": INK_MUTED}, xanchor=\"center\"\n)\n\n# Title: 62 chars — under 67, default 16px applies, no scaling needed\ntitle = \"Higgs-strahlung · feynman-basic · python · plotly · anyplot.ai\"\n\nfig.update_layout(\n    autosize=False,\n    margin={\"l\": 40, \"r\": 40, \"t\": 70, \"b\": 40},\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK, \"family\": \"serif\"},\n    title={\"text\": title, \"font\": {\"size\": 16, \"family\": \"serif\"}, \"x\": 0.5, \"xanchor\": \"center\"},\n    xaxis={\"visible\": False, \"range\": [-0.06, 1.10], \"fixedrange\": True},\n    yaxis={\"visible\": False, \"range\": [-0.20, 1.05], \"fixedrange\": True},\n    showlegend=False,\n)\n\n# Save — canvas: 3200 × 1800 (landscape)\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}