{"spec_id":"scatter-3d","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\nscatter-3d: 3D Scatter Plot\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 83/100 | Created: 2026-05-08\n\"\"\"\n\nimport os\nimport site\nimport sys\n\nimport numpy as np\n\n\nsys.path.insert(0, site.getsitepackages()[0])\n\nimport pygal\nfrom pygal.style import Style\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\nnp.random.seed(42)\nn_samples = 150\nn_clusters = 3\n\nclusters_x = np.random.uniform(10, 90, n_clusters)\nclusters_y = np.random.uniform(20, 80, n_clusters)\nclusters_z = np.random.uniform(15, 85, n_clusters)\n\npoints_x = []\npoints_y = []\npoints_z = []\n\nfor i in range(n_clusters):\n    cluster_points_x = np.random.normal(clusters_x[i], 8, n_samples // n_clusters)\n    cluster_points_y = np.random.normal(clusters_y[i], 8, n_samples // n_clusters)\n    cluster_points_z = np.random.normal(clusters_z[i], 8, n_samples // n_clusters)\n\n    points_x.extend(cluster_points_x)\n    points_y.extend(cluster_points_y)\n    points_z.extend(cluster_points_z)\n\npoints_x = np.array(points_x)\npoints_y = np.array(points_y)\npoints_z = np.array(points_z)\n\nz_norm = (points_z - points_z.min()) / (points_z.max() - points_z.min())\n\n\ndef viridis(t):\n    \"\"\"Approximate viridis colormap (t in [0, 1]).\"\"\"\n    if t < 0.5:\n        r = int(68 + (33 - 68) * (t * 2))\n        g = int(1 + (145 - 1) * (t * 2))\n        b = int(84 + (140 - 84) * (t * 2))\n    else:\n        r = int(33 + (253 - 33) * ((t - 0.5) * 2))\n        g = int(145 + (231 - 145) * ((t - 0.5) * 2))\n        b = int(140 + (37 - 140) * ((t - 0.5) * 2))\n    return f\"#{r:02x}{g:02x}{b:02x}\"\n\n\nz_hex_colors = tuple(viridis(z) for z in z_norm)\n\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=PAGE_BG,\n    foreground=INK,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=z_hex_colors,\n    title_font_size=28,\n    label_font_size=22,\n    major_label_font_size=18,\n    legend_font_size=16,\n    stroke_width=0,\n)\n\nchart = pygal.XY(\n    width=4800,\n    height=2700,\n    style=custom_style,\n    title=\"scatter-3d (Z encoded by color) · pygal · anyplot.ai\",\n    x_title=\"X Dimension\",\n    y_title=\"Y Dimension\",\n    show_legend=False,\n    show_dots=True,\n    dots_size=7,\n)\n\nfor i in range(n_samples):\n    chart.add(f\"Z: {points_z[i]:.1f}\", [(points_x[i], points_y[i])])\n\nchart.render_to_png(f\"plot-{THEME}.png\")\n\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}