{"spec_id":"scatter-text","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nscatter-text: Scatter Plot with Text Labels Instead of Points\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib.lines import Line2D\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\"\n\n# Okabe-Ito palette (first series always #009E73)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data - Stock symbols positioned by market metrics (market cap vs growth similarity)\nnp.random.seed(42)\n\nstocks = [\n    \"AAPL\",\n    \"MSFT\",\n    \"GOOGL\",\n    \"AMZN\",\n    \"NVDA\",\n    \"TSLA\",\n    \"META\",\n    \"NFLX\",\n    \"COIN\",\n    \"RIOT\",\n    \"JPM\",\n    \"BAC\",\n    \"GS\",\n    \"WFC\",\n    \"XOM\",\n    \"CVX\",\n    \"JNJ\",\n    \"PFE\",\n    \"AbbV\",\n    \"MRK\",\n    \"WMT\",\n    \"TGT\",\n    \"AZO\",\n    \"HD\",\n]\n\n# Generate well-separated coordinates (simulating market embedding)\nbase_x = np.array(\n    [\n        -2.5,\n        -2.0,\n        -2.2,\n        -2.8,\n        -1.8,\n        -1.2,\n        -1.5,\n        -0.8,\n        0.2,\n        1.2,\n        2.5,\n        2.8,\n        3.2,\n        3.0,\n        -0.5,\n        0.3,\n        1.5,\n        1.8,\n        2.0,\n        2.3,\n        0.8,\n        1.0,\n        2.5,\n        0.2,\n    ]\n)\n\nbase_y = np.array(\n    [\n        3.5,\n        3.2,\n        2.8,\n        3.8,\n        4.0,\n        3.0,\n        2.5,\n        2.2,\n        1.8,\n        0.5,\n        -3.0,\n        -3.5,\n        -2.8,\n        -3.2,\n        -2.5,\n        -2.0,\n        -1.5,\n        -1.2,\n        -0.8,\n        -1.0,\n        1.0,\n        0.3,\n        1.5,\n        0.8,\n    ]\n)\n\n# Add small jitter to prevent exact overlaps\nx = base_x + np.random.uniform(-0.15, 0.15, len(base_x))\ny = base_y + np.random.uniform(-0.15, 0.15, len(base_y))\n\n# Define sectors for coloring\nsectors = [\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Technology\",\n    \"Cryptocurrency\",\n    \"Cryptocurrency\",\n    \"Finance\",\n    \"Finance\",\n    \"Finance\",\n    \"Finance\",\n    \"Energy\",\n    \"Energy\",\n    \"Healthcare\",\n    \"Healthcare\",\n    \"Healthcare\",\n    \"Healthcare\",\n    \"Retail\",\n    \"Retail\",\n    \"Retail\",\n    \"Retail\",\n]\n\n# Create DataFrame\ndf = pd.DataFrame({\"x\": x, \"y\": y, \"ticker\": stocks, \"sector\": sectors})\n\n# Map sectors to Okabe-Ito colors\nsector_color_map = {\n    \"Technology\": IMPRINT[0],\n    \"Cryptocurrency\": IMPRINT[1],\n    \"Finance\": IMPRINT[2],\n    \"Energy\": IMPRINT[3],\n    \"Healthcare\": IMPRINT[4],\n    \"Retail\": IMPRINT[5],\n}\n\n# Set seaborn theme with theme-adaptive colors\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n    },\n)\n\n# Create figure and axis\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Plot text labels at each coordinate position\nfor _, row in df.iterrows():\n    color = sector_color_map[row[\"sector\"]]\n    ax.text(\n        row[\"x\"],\n        row[\"y\"],\n        row[\"ticker\"],\n        fontsize=20,\n        fontweight=\"bold\",\n        ha=\"center\",\n        va=\"center\",\n        color=color,\n        alpha=0.85,\n    )\n\n# Styling\nax.set_xlabel(\"Market Cap Similarity (Dim 1)\", fontsize=20, color=INK)\nax.set_ylabel(\"Growth Profile (Dim 2)\", fontsize=20, color=INK)\nax.set_title(\"scatter-text · Python · seaborn · anyplot.ai\", fontsize=24, color=INK)\n\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\n\n# Remove top and right spines\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_color(INK_SOFT)\n\n# Subtle grid\nax.yaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK)\n\n# Create legend with sector colors\nlegend_elements = [\n    Line2D([0], [0], marker=\"o\", color=\"w\", markerfacecolor=color, markersize=10, label=sector)\n    for sector, color in sector_color_map.items()\n]\nax.legend(\n    handles=legend_elements,\n    title=\"Sector\",\n    loc=\"upper left\",\n    framealpha=0.95,\n    facecolor=ELEVATED_BG,\n    edgecolor=INK_SOFT,\n    fontsize=14,\n    title_fontsize=16,\n)\n\n# Set axis limits with padding\nx_margin = 0.8\ny_margin = 0.8\nax.set_xlim(x.min() - x_margin, x.max() + x_margin)\nax.set_ylim(y.min() - y_margin, y.max() + y_margin)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}