{"spec_id":"scatter-text","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nscatter-text: Scatter Plot with Text Labels Instead of Points\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 84/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\n\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\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Okabe-Ito palette for categories\nIMPRINT = [\n    \"#009E73\",  # bluish green (brand)\n    \"#C475FD\",  # vermillion\n    \"#4467A3\",  # blue\n    \"#BD8233\",  # reddish purple\n    \"#AE3030\",  # orange\n    \"#2ABCCD\",  # sky blue\n    \"#954477\",  # yellow\n    \"#1A1A1A\" if THEME == \"light\" else \"#E8E8E0\",  # adaptive neutral\n]\n\n# Data - Programming languages positioned by paradigm characteristics\nlabels = [\n    \"Python\",\n    \"JavaScript\",\n    \"Java\",\n    \"C++\",\n    \"Ruby\",\n    \"Go\",\n    \"Rust\",\n    \"Kotlin\",\n    \"Swift\",\n    \"TypeScript\",\n    \"Scala\",\n    \"Haskell\",\n    \"Elixir\",\n    \"Clojure\",\n    \"F#\",\n    \"R\",\n    \"Julia\",\n    \"MATLAB\",\n    \"Perl\",\n    \"PHP\",\n    \"C#\",\n    \"Dart\",\n    \"Lua\",\n    \"Erlang\",\n    \"OCaml\",\n    \"Fortran\",\n    \"COBOL\",\n    \"Assembly\",\n    \"Lisp\",\n    \"Prolog\",\n]\n\n# Position based on: x = Level of abstraction, y = Type safety\n# Improved coordinates to reduce clustering\nx = [\n    8.5,  # Python\n    5.0,  # JavaScript - shifted further left\n    6.5,  # Java\n    3.0,  # C++\n    8.0,  # Ruby\n    5.0,  # Go\n    4.0,  # Rust\n    5.5,  # Kotlin\n    7.0,  # Swift\n    7.5,  # TypeScript\n    6.0,  # Scala\n    9.0,  # Haskell\n    8.5,  # Elixir\n    9.8,  # Clojure\n    8.0,  # F#\n    9.5,  # R\n    7.5,  # Julia\n    6.5,  # MATLAB\n    8.5,  # Perl\n    7.0,  # PHP\n    6.0,  # C#\n    8.0,  # Dart\n    6.0,  # Lua\n    9.2,  # Erlang\n    8.5,  # OCaml\n    2.0,  # Fortran\n    5.0,  # COBOL\n    1.0,  # Assembly\n    9.5,  # Lisp\n    7.5,  # Prolog\n]\n\ny = [\n    3.0,  # Python\n    1.5,  # JavaScript\n    8.0,  # Java\n    6.0,  # C++\n    1.5,  # Ruby\n    7.0,  # Go\n    9.0,  # Rust\n    8.5,  # Kotlin\n    9.0,  # Swift\n    7.0,  # TypeScript\n    9.0,  # Scala\n    9.5,  # Haskell\n    5.5,  # Elixir\n    4.5,  # Clojure\n    8.5,  # F#\n    3.0,  # R\n    4.5,  # Julia\n    3.0,  # MATLAB\n    2.5,  # Perl\n    1.5,  # PHP\n    8.5,  # C#\n    6.0,  # Dart\n    4.0,  # Lua\n    6.5,  # Erlang\n    9.5,  # OCaml\n    3.5,  # Fortran\n    6.5,  # COBOL\n    2.5,  # Assembly\n    5.0,  # Lisp\n    8.0,  # Prolog\n]\n\n# Assign to Okabe-Ito positions by paradigm\ncategories = [\n    0,  # Python - bluish green (brand)\n    2,  # JavaScript - blue\n    1,  # Java - vermillion\n    7,  # C++ - neutral\n    1,  # Ruby - vermillion\n    4,  # Go - orange\n    7,  # Rust - neutral\n    3,  # Kotlin - reddish purple\n    3,  # Swift - reddish purple\n    2,  # TypeScript - blue\n    5,  # Scala - sky blue\n    0,  # Haskell - bluish green\n    6,  # Elixir - yellow\n    5,  # Clojure - sky blue\n    5,  # F# - sky blue\n    0,  # R - bluish green\n    0,  # Julia - bluish green\n    4,  # MATLAB - orange\n    1,  # Perl - vermillion\n    1,  # PHP - vermillion\n    3,  # C# - reddish purple\n    3,  # Dart - reddish purple\n    1,  # Lua - vermillion\n    6,  # Erlang - yellow\n    5,  # OCaml - sky blue\n    7,  # Fortran - neutral\n    7,  # COBOL - neutral\n    7,  # Assembly - neutral\n    0,  # Lisp - bluish green\n    0,  # Prolog - bluish green\n]\n\ncategory_names = [\"Functional\", \"OOP\", \"Multi-paradigm\", \"OOP\", \"Systems\", \"Functional\", \"Scripting\", \"Paradigm Mix\"]\n\n# Create figure with text labels as data points\nfig = go.Figure()\n\n# Add text labels grouped by category for legend\ncategory_colors = {}\nfor cat_idx, cat_name in enumerate(category_names):\n    mask = [c == cat_idx for c in categories]\n    if any(mask):\n        x_cat = [x[i] for i in range(len(x)) if mask[i]]\n        y_cat = [y[i] for i in range(len(y)) if mask[i]]\n        labels_cat = [labels[i] for i in range(len(labels)) if mask[i]]\n\n        color = IMPRINT[cat_idx]\n        category_colors[cat_name] = color\n\n        # Create hover text with detailed information\n        hover_cat = [\n            f\"<b>{labels[i]}</b><br>Abstraction: {x[i]:.1f}<br>Type Safety: {y[i]:.1f}\"\n            for i in range(len(labels))\n            if mask[i]\n        ]\n\n        fig.add_trace(\n            go.Scatter(\n                x=x_cat,\n                y=y_cat,\n                mode=\"text\",\n                text=labels_cat,\n                textfont=dict(size=18, color=color),\n                textposition=\"middle center\",\n                name=cat_name,\n                showlegend=True,\n                hovertext=hover_cat,\n                hoverinfo=\"text\",\n            )\n        )\n\n# Update layout with theme-adaptive colors\nfig.update_layout(\n    title=dict(\n        text=\"scatter-text · Python · plotly · anyplot.ai\", font=dict(size=28, color=INK), x=0.5, xanchor=\"center\"\n    ),\n    xaxis=dict(\n        title=dict(text=\"Level of Abstraction\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        range=[0, 10.5],\n        gridcolor=GRID,\n        gridwidth=1,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Type Safety\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        range=[0, 10.5],\n        gridcolor=GRID,\n        gridwidth=1,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    legend=dict(\n        title=dict(text=\"Category\", font=dict(size=18, color=INK)),\n        font=dict(size=16, color=INK_SOFT),\n        bgcolor=ELEVATED_BG,\n        bordercolor=INK_SOFT,\n        borderwidth=1,\n        x=1.02,\n        y=0.98,\n        xanchor=\"left\",\n        yanchor=\"top\",\n    ),\n    margin=dict(l=100, r=180, t=100, b=100),\n    font=dict(family=\"Arial\"),\n)\n\n# Save as PNG and HTML\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}