{"spec_id":"pictogram-basic","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\npictogram-basic: Pictogram Chart (Isotype Visualization)\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-06-03\n\"\"\"\n\nimport os\nimport sys\n\n\n# The script is named pygal.py — prevent it from shadowing the installed pygal package.\n_script_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p) != _script_dir]\n\nimport pygal\nfrom pygal.style import Style\n\n\n# Theme tokens — Imprint palette, theme-adaptive chrome\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette — canonical order, first series always #009E73\nIMPRINT_PALETTE = (\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\")\n\n# Data — fruit production (thousands of tonnes), descending for visual hierarchy\ncategories = [\"Apples\", \"Oranges\", \"Bananas\", \"Grapes\", \"Mangoes\"]\nvalues = [35, 22, 18, 15, 8]\nicon_unit = 5  # each dot represents 5 thousand tonnes\n\n# Build dot matrix: 1.0 = full icon, fraction = proportional partial, None = empty\nmax_icons = max(v // icon_unit + (1 if v % icon_unit else 0) for v in values)\ndot_data = {}\nfor cat, val in zip(categories, values, strict=True):\n    full = val // icon_unit\n    remainder = val % icon_unit\n    row = [1.0] * full\n    if remainder:\n        row.append(remainder / icon_unit)  # proportional fraction for accurate partial\n    row += [None] * (max_icons - len(row))\n    dot_data[cat] = row\n\n# Title length-aware font size (baseline: 67 chars → size 66)\ntitle = \"Fruit Production · pictogram-basic · python · pygal · anyplot.ai\"\ntitle_n = len(title)\ntitle_fontsize = max(44, round(66 * (67 / title_n if title_n > 67 else 1.0)))\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=IMPRINT_PALETTE,\n    title_font_size=title_fontsize,\n    label_font_size=56,\n    major_label_font_size=44,\n    legend_font_size=44,\n    value_font_size=36,\n    stroke_width=2.5,\n    font_family=\"Helvetica, Arial, sans-serif\",\n)\n\nchart = pygal.Dot(\n    width=3200,\n    height=1800,\n    style=custom_style,\n    title=title,\n    x_title=\"Thousands of tonnes  ·  each dot = 5k t\",\n    show_legend=True,\n    legend_at_bottom=True,\n    legend_at_bottom_columns=5,\n    legend_box_size=28,\n    show_x_guides=False,\n    show_y_guides=False,\n    show_x_labels=True,\n    spacing=35,\n    margin=50,\n    margin_left=110,\n    margin_right=80,\n    margin_top=80,\n    margin_bottom=170,\n    x_label_rotation=0,\n    truncate_label=-1,\n    truncate_legend=-1,\n    dot_size=46,\n    print_values=False,\n    stroke=False,\n    value_formatter=lambda v: f\"{int(round(v * icon_unit))}k t\" if v else \"\",\n)\n\n# X-axis labels show cumulative scale in thousands\nchart.x_labels = [f\"{(i + 1) * icon_unit}k\" for i in range(max_icons)]\n\n# Add each category as a series — Imprint palette cycles in canonical order\nfor cat in categories:\n    chart.add(cat, dot_data[cat])\n\n# Save — theme-suffixed filenames, PNG + interactive HTML\nchart.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}