{"spec_id":"scatter-basic","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\nscatter-basic: Basic Scatter Plot\nLibrary: pygal 3.1.3 | Python 3.13.14\nQuality: 87/100 | Updated: 2026-06-25\n\"\"\"\n\nimport os\nimport sys\n\n\n# Script filename shadows the installed `pygal` package when run as `python pygal.py`;\n# dropping the script directory from sys.path lets the real package resolve.\nsys.path.pop(0)\n\nimport numpy as np\nimport pygal\nfrom pygal.style import Style\n\n\n# Theme tokens\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\n# Imprint palette — canonical order; semantic positions used for pass/fail split\n# First series = brand green (#009E73), fail = matte red (#AE3030)\nIMPRINT = (\n    \"#009E73\",  # position 1: brand green → Passing\n    \"#AE3030\",  # position 5: matte red (semantic anchor for bad/fail) → Below 70%\n    \"#C475FD\",\n    \"#4467A3\",\n    \"#BD8233\",\n    \"#2ABCCD\",\n    \"#954477\",\n    \"#99B314\",\n)\n\n# Data — study hours vs exam scores, moderate positive correlation\nnp.random.seed(42)\nn = 180\nstudy_hours = np.random.uniform(1.5, 13.5, n)\nexam_scores = study_hours * 4.8 + np.random.normal(0, 6.5, n) + 26\nexam_scores = np.clip(exam_scores, 20, 100)\n\n# Visual hierarchy: split at conventional 70% passing threshold to guide the\n# viewer's eye and convey the \"hours → outcome\" narrative beyond a raw cloud.\nPASSING = 70.0\nabove = [(float(h), float(s)) for h, s in zip(study_hours, exam_scores, strict=True) if s >= PASSING]\nbelow = [(float(h), float(s)) for h, s in zip(study_hours, exam_scores, strict=True) if s < PASSING]\n\nfont = \"DejaVu Sans, Helvetica, Arial, sans-serif\"\n\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=PAGE_BG,\n    foreground=INK_SOFT,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=IMPRINT,\n    font_family=font,\n    title_font_family=font,\n    label_font_family=font,\n    major_label_font_family=font,\n    legend_font_family=font,\n    tooltip_font_family=font,\n    title_font_size=66,\n    label_font_size=56,\n    major_label_font_size=44,\n    legend_font_size=44,\n    tooltip_font_size=36,\n    value_font_size=36,\n    opacity=0.72,\n    opacity_hover=0.95,\n    stroke_opacity=1,\n    stroke_opacity_hover=1,\n)\n\nchart = pygal.XY(\n    width=3200,\n    height=1800,\n    style=custom_style,\n    title=\"scatter-basic · python · pygal · anyplot.ai\",\n    x_title=\"Study Hours per Week (hrs)\",\n    y_title=\"Exam Score (%)\",\n    stroke=False,\n    dots_size=12,\n    show_legend=True,\n    legend_at_bottom=True,\n    legend_at_bottom_columns=2,\n    legend_box_size=32,\n    show_x_guides=True,\n    show_y_guides=True,\n    x_value_formatter=lambda v: f\"{v:.0f}\",\n    value_formatter=lambda v: f\"{v:.0f}%\",\n    range=(15, 100),\n    xrange=(1, 14),\n    x_labels_major_count=7,\n    y_labels_major_count=9,\n    margin=60,\n    print_values=False,\n    js=[],\n)\n\nchart.add(\"Passing (≥ 70%)\", above)\nchart.add(\"Below 70%\", below)\n\nchart.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}