{"spec_id":"scatter-embedding","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nscatter-embedding: t-SNE and UMAP Embedding Visualization\nLibrary: letsplot 4.11.0 | Python 3.13.14\nQuality: 94/100 | Updated: 2026-08-11\n\"\"\"\n\nimport os\nimport shutil\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\nfrom sklearn.datasets import make_blobs\nfrom sklearn.manifold import TSNE\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 — first series always #009E73\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\"]\n\n# Data — simulate single-cell RNA-seq gene expression then embed via t-SNE\nnp.random.seed(42)\nX, y = make_blobs(n_samples=1500, centers=6, n_features=20, cluster_std=2.8)\ncell_types = [\"T-cell\", \"B-cell\", \"NK-cell\", \"Monocyte\", \"Dendritic\", \"Neutrophil\"]\nlabels = [cell_types[i] for i in y]\n\ntsne = TSNE(n_components=2, perplexity=30, random_state=42, max_iter=1000)\ncoords = tsne.fit_transform(X)\n\ndf = pd.DataFrame({\"tsne_1\": coords[:, 0], \"tsne_2\": coords[:, 1], \"cell_type\": labels})\ncentroids = df.groupby(\"cell_type\", as_index=False)[[\"tsne_1\", \"tsne_2\"]].mean()\n\n# Theme — sized for the 3200x1800 canvas (ggsize(800, 450) x scale=4)\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    panel_grid_major=element_blank(),\n    panel_grid_minor=element_blank(),\n    panel_border=element_blank(),\n    axis_title=element_text(color=INK, size=12),\n    axis_text=element_blank(),\n    axis_ticks=element_blank(),\n    axis_line=element_blank(),\n    plot_title=element_text(color=INK, size=16),\n    plot_subtitle=element_text(color=INK_SOFT, size=13),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(color=INK_SOFT, size=10),\n    legend_title=element_text(color=INK, size=11),\n)\n\n# Plot — points carry a tooltip (cell type + coordinates); centroids get a\n# boxed label so clusters are identifiable even with the legend collapsed.\nplot = (\n    ggplot(df, aes(x=\"tsne_1\", y=\"tsne_2\", color=\"cell_type\"))\n    + geom_density2d(size=0.4, alpha=0.5, bins=4, show_legend=False)\n    + geom_point(\n        size=2.1,\n        alpha=0.5,\n        tooltips=layer_tooltips().line(\"Cell type|@cell_type\").line(\"t-SNE 1|@tsne_1\").line(\"t-SNE 2|@tsne_2\"),\n    )\n    + geom_label(\n        aes(x=\"tsne_1\", y=\"tsne_2\", label=\"cell_type\"),\n        data=centroids,\n        color=INK,\n        fill=ELEVATED_BG,\n        size=4,\n        fontface=\"bold\",\n        label_padding=0.3,\n        show_legend=False,\n    )\n    + scale_color_manual(values=IMPRINT)\n    + labs(\n        x=\"t-SNE 1\",\n        y=\"t-SNE 2\",\n        color=\"Cell Type\",\n        title=\"scatter-embedding · python · letsplot · anyplot.ai\",\n        subtitle=\"t-SNE (perplexity=30) · Single-cell RNA-seq Cell Type Clusters\",\n    )\n    + ggsize(800, 450)\n    + anyplot_theme\n)\n\n# Save\nggsave(plot, f\"plot-{THEME}.png\", scale=4, path=\".\")\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n\nif os.path.exists(\"lets-plot-images\"):\n    shutil.rmtree(\"lets-plot-images\")\n"}