{"spec_id":"treemap-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\ntreemap-basic: Basic Treemap\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 85/100 | Updated: 2026-08-04\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nimport squarify\nfrom matplotlib.patches import Patch, Rectangle\n\n\nnp.random.seed(42)\n\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\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"text.color\": INK,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Imprint palette — canonical order, first series always #009E73\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data - Disk usage by storage device and data type (GB)\ndata = [\n    (\"SSD-1\", \"Documents\", 120),\n    (\"SSD-1\", \"Media\", 85),\n    (\"SSD-1\", \"Cache\", 45),\n    (\"SSD-2\", \"Applications\", 150),\n    (\"SSD-2\", \"System\", 60),\n    (\"HDD-1\", \"Archives\", 320),\n    (\"HDD-1\", \"Backups\", 280),\n    (\"HDD-2\", \"Videos\", 410),\n    (\"HDD-2\", \"Photos\", 190),\n    (\"Cloud\", \"Sync\", 75),\n    (\"Cloud\", \"Versioning\", 40),\n]\n\ncategories = [d[0] for d in data]\nsubcategories = [d[1] for d in data]\nvalues = [d[2] for d in data]\n\nunique_categories = [\"SSD-1\", \"SSD-2\", \"HDD-1\", \"HDD-2\", \"Cloud\"]\ncategory_colors = dict(zip(unique_categories, IMPRINT, strict=False))\n\nwidth, height = 160, 90\n\nrects = squarify.normalize_sizes(values, width, height)\nrects = squarify.squarify(rects, 0, 0, width, height)\n\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\ncategory_counts = {}\ncategory_indices = {}\nfor i, cat in enumerate(categories):\n    if cat not in category_counts:\n        category_counts[cat] = 0\n        category_indices[cat] = []\n    category_indices[cat].append(i)\n    category_counts[cat] += 1\n\n# The single largest rectangle by area anchors the visual hierarchy — the reader's\n# eye should land there first, so it gets a bolder outline than the rest.\nlargest_idx = max(range(len(rects)), key=lambda i: rects[i][\"dx\"] * rects[i][\"dy\"])\n\nfor i, rect in enumerate(rects):\n    cat = categories[i]\n    base_color = category_colors[cat]\n\n    cat_items = category_indices[cat]\n    rank_in_category = cat_items.index(i)\n    num_in_category = len(cat_items)\n\n    shades = sns.light_palette(base_color, n_colors=num_in_category + 2, reverse=True)\n    shade_color = shades[rank_in_category + 1]\n\n    is_largest = i == largest_idx\n    rectangle = Rectangle(\n        (rect[\"x\"], rect[\"y\"]),\n        rect[\"dx\"],\n        rect[\"dy\"],\n        facecolor=shade_color,\n        edgecolor=INK if is_largest else PAGE_BG,\n        linewidth=4.5 if is_largest else 3,\n        alpha=0.92,\n    )\n    ax.add_patch(rectangle)\n\n    area = rect[\"dx\"] * rect[\"dy\"]\n    if area > 150:\n        r_val, g_val, b_val = shade_color[:3]\n        luminance = 0.299 * r_val + 0.587 * g_val + 0.114 * b_val\n        text_color = \"#1A1A17\" if luminance > 0.5 else \"#FFFFFF\"\n        fontsize = min(18, max(12, int(area**0.35)))\n\n        label = f\"{subcategories[i]}\\n{values[i]}GB\"\n        ax.text(\n            rect[\"x\"] + rect[\"dx\"] / 2,\n            rect[\"y\"] + rect[\"dy\"] / 2,\n            label,\n            ha=\"center\",\n            va=\"center\",\n            fontsize=fontsize,\n            fontweight=\"bold\",\n            color=text_color,\n        )\n\nax.set_xlim(0, width)\nax.set_ylim(0, height)\nax.axis(\"off\")\nax.set_aspect(\"equal\")\n\ntitle = \"Disk Usage by Device · treemap-basic · python · seaborn · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * min(1.0, 67 / len(title))))\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=14)\n\nlegend_handles = [Patch(facecolor=category_colors[cat], label=cat, edgecolor=INK_SOFT) for cat in unique_categories]\nax.legend(\n    handles=legend_handles,\n    loc=\"upper center\",\n    fontsize=8,\n    framealpha=0.95,\n    facecolor=ELEVATED_BG,\n    edgecolor=INK_SOFT,\n    ncol=5,\n    bbox_to_anchor=(0.5, -0.02),\n)\n\nfig.subplots_adjust(left=0.02, right=0.98, top=0.88, bottom=0.1)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}