Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 43 additions & 18 deletions plots/treemap-basic/implementations/python/plotnine.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
""" anyplot.ai
treemap-basic: Basic Treemap
Library: plotnine 0.15.4 | Python 3.13.13
Quality: 80/100 | Updated: 2026-05-05
Quality: 80/100 | Updated: 2026-08-04
"""

import os

import pandas as pd
from plotnine import aes, element_text, geom_rect, geom_text, ggplot, labs, scale_fill_manual, theme, theme_void
from plotnine import (
aes,
element_rect,
element_text,
geom_rect,
geom_text,
ggplot,
labs,
scale_fill_manual,
theme,
theme_void,
)


# Theme-adaptive tokens (Imprint palette + chrome)
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"

# Data - Budget allocation by department
data = {
"category": [
Expand Down Expand Up @@ -141,35 +161,40 @@
df["xcenter"] = df["x"] + df["dx"] / 2
df["ycenter"] = df["y"] + df["dy"] / 2

# Create combined label with value
df["label"] = df["subcategory"] + "\n$" + df["value"].astype(str) + "K"
# Label larger rectangles with subcategory + value; smallest ones stay unlabeled for clarity
df["label"] = [f"{sub}\n${val}K" if val >= 100 else "" for sub, val in zip(df["subcategory"], df["value"], strict=True)]

# Color palette for categories (Python Blue and Yellow first, then colorblind-safe)
# Imprint palette, canonical order (first series is always #009E73)
category_colors = {
"Engineering": "#306998", # Python Blue
"Marketing": "#FFD43B", # Python Yellow
"Sales": "#4ECDC4", # Teal
"Operations": "#FF6B6B", # Coral
"HR": "#95E1A3", # Light green
"Finance": "#DDA0DD", # Plum
"Engineering": "#009E73",
"Marketing": "#C475FD",
"Sales": "#4467A3",
"Operations": "#BD8233",
"HR": "#AE3030",
"Finance": "#2ABCCD",
}

title = "Budget Allocation by Department 路 treemap-basic 路 python 路 plotnine 路 anyplot.ai"

# Create plot
plot = (
ggplot(df)
+ geom_rect(aes(xmin="xmin", xmax="xmax", ymin="ymin", ymax="ymax", fill="category"), color="white", size=2)
+ geom_text(aes(x="xcenter", y="ycenter", label="label"), size=12, color="black", fontweight="bold")
+ geom_text(aes(x="xcenter", y="ycenter", label="label"), size=4, color=INK, fontweight="bold")
+ scale_fill_manual(values=category_colors)
+ labs(title="Budget Allocation by Department 路 treemap-basic 路 plotnine 路 pyplots.ai", fill="Department")
+ labs(title=title, fill="Department")
+ theme_void()
+ theme(
figure_size=(16, 9),
plot_title=element_text(size=24, ha="center", weight="bold", margin={"b": 20}),
legend_title=element_text(size=18),
legend_text=element_text(size=16),
figure_size=(8, 4.5),
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
plot_title=element_text(size=10, ha="center", weight="bold", color=INK, margin={"b": 12}),
legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),
legend_title=element_text(size=9, color=INK),
legend_text=element_text(size=8, color=INK_SOFT),
legend_position="right",
)
)

# Save
plot.save("plot.png", dpi=300, verbose=False)
plot.save(f"plot-{THEME}.png", dpi=400, width=8, height=4.5, units="in", verbose=False)
233 changes: 11 additions & 222 deletions plots/treemap-basic/metadata/python/plotnine.yaml
Original file line number Diff line number Diff line change
@@ -1,232 +1,21 @@
# Per-library metadata for plotnine implementation of treemap-basic
# Auto-generated by impl-generate.yml

library: plotnine
language: python
specification_id: treemap-basic
created: '2025-12-24T09:50:34Z'
updated: '2026-05-05T22:53:16Z'
generated_by: claude-haiku
workflow_run: 25406195588
updated: '2026-08-04T08:59:59Z'
generated_by: claude-sonnet
workflow_run: 30893928691
issue: 766
python_version: 3.13.13
library_version: 0.15.4
language_version: 3.13.14
library_version: 0.15.7
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/treemap-basic/python/plotnine/plot-light.png
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/treemap-basic/python/plotnine/plot-dark.png
preview_html_light: null
preview_html_dark: null
quality_score: 80
quality_score: null
review:
strengths:
- Correct treemap implementation with squarified layout algorithm proportioning
rectangles to values
- Readable in both light and dark themes with clear visual hierarchy
- Realistic, neutral budget allocation data with excellent hierarchical representation
- Clean, balanced layout with generous whitespace and no overlapping elements
- Rectangle size and color both aid understanding of budget distribution across
departments
weaknesses:
- 'Palette does not follow Okabe-Ito spec: uses custom colors (Python Blue, Yellow,
Teal, etc.) instead of starting with #009E73 (hard rule violation)'
- 'Title contains typo: ''pyplots.ai'' should be ''anyplot.ai'''
- 'Text color hardcoded to black instead of theme-adaptive: does not read ANYPLOT_THEME
environment variable or use INK/INK_SOFT tokens'
- 'Output filename ''plot.png'' does not match API specification: should save to
f''plot-{THEME}.png'' and read environment variable'
image_description: |-
Light render (plot-light.png):
Background: Warm off-white (#FAF8F1) as specified in style guide
Chrome: Title in dark text ("Budget Allocation by Department 路 treemap-basic 路 plotnine 路 pyplots.ai") centered at top; Department legend on right with clear labels; all text readable against light background
Data: Six department categories color-coded (Engineering=Python Blue, Marketing=Yellow, Sales=Teal, Operations=Coral, HR=Light Green, Finance=Plum); rectangle areas proportional to budget values ($80K-$450K); white borders separate rectangles; subcategory labels and dollar amounts displayed in dark text centered in each rectangle
Legibility verdict: PASS - All text is readable, though some text on darker rectangle backgrounds (dark green for Engineering, coral for Operations) has reduced contrast but remains legible at full resolution

Dark render (plot-dark.png):
Background: Warm near-black (#1A1A17) as specified in style guide
Chrome: Title in light text (appears white), readable against dark background; Department legend on right with light text; all chrome elements clearly visible
Data: Rectangle fills are identical to light render (same category colors); white borders provide contrast; labels display in white/light text, readable against both dark background and colored rectangles
Legibility verdict: PASS - No dark-on-dark failures; all text is clearly distinguishable. Data colors identical to light render; only chrome (background, text, legend frame) adapts to dark theme as intended
criteria_checklist:
visual_quality:
score: 24
max: 30
items:
- id: VQ-01
name: Text Legibility
score: 6
max: 8
passed: true
comment: Readable in both renders; code hardcodes black instead of using theme-adaptive
tokens
- id: VQ-02
name: No Overlap
score: 6
max: 6
passed: true
comment: No overlapping text; labels well-positioned in rectangle centers
- id: VQ-03
name: Element Visibility
score: 6
max: 6
passed: true
comment: All rectangles and labels visible; white borders provide clear separation
- id: VQ-04
name: Color Accessibility
score: 1
max: 2
passed: false
comment: Colors are distinct and CVD-safe but don't use Okabe-Ito palette
- id: VQ-05
name: Layout & Canvas
score: 4
max: 4
passed: true
comment: Excellent 16:9 proportions with balanced margins and whitespace
- id: VQ-06
name: Axis Labels & Title
score: 1
max: 2
passed: false
comment: 'Title has typo: ''pyplots.ai'' should be ''anyplot.ai'''
- id: VQ-07
name: Palette Compliance
score: 0
max: 2
passed: false
comment: 'Uses custom palette instead of Okabe-Ito; first category should
be #009E73 not Python Blue'
design_excellence:
score: 12
max: 20
items:
- id: DE-01
name: Aesthetic Sophistication
score: 4
max: 8
passed: false
comment: Custom palette chosen but violates hard palette rules; default raised
minimally
- id: DE-02
name: Visual Refinement
score: 4
max: 6
passed: true
comment: White borders add definition; theme_void() is clean; generous whitespace
- id: DE-03
name: Data Storytelling
score: 4
max: 6
passed: true
comment: Clear hierarchy through rectangle size; color aids department identification
spec_compliance:
score: 14
max: 15
items:
- id: SC-01
name: Plot Type
score: 5
max: 5
passed: true
comment: Correct treemap with squarified layout
- id: SC-02
name: Required Features
score: 4
max: 4
passed: true
comment: 'All spec features present: categories, subcategories, values, colors,
labels, borders'
- id: SC-03
name: Data Mapping
score: 3
max: 3
passed: true
comment: Value-to-area mapping correct; all data visible
- id: SC-04
name: Title & Legend
score: 2
max: 3
passed: false
comment: Legend correct; title format correct except typo (pyplots.ai not
anyplot.ai)
data_quality:
score: 15
max: 15
items:
- id: DQ-01
name: Feature Coverage
score: 6
max: 6
passed: true
comment: Full hierarchical structure with color coding, proportional sizing,
and labeled values
- id: DQ-02
name: Realistic Context
score: 5
max: 5
passed: true
comment: Budget allocation is realistic and neutral domain
- id: DQ-03
name: Appropriate Scale
score: 4
max: 4
passed: true
comment: Budget ranges ($80K-$450K) plausible for company allocation
code_quality:
score: 9
max: 10
items:
- id: CQ-01
name: KISS Structure
score: 3
max: 3
passed: true
comment: No unnecessary abstractions; inline algorithm is necessary
- id: CQ-02
name: Reproducibility
score: 2
max: 2
passed: true
comment: Hardcoded data and deterministic algorithm
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
comment: All imports used; no clutter
- id: CQ-04
name: Code Elegance
score: 2
max: 2
passed: true
comment: No fake UI; appropriate complexity
- id: CQ-05
name: Output & API
score: 0
max: 1
passed: false
comment: Saves to 'plot.png' instead of 'plot-{THEME}.png'; doesn't read ANYPLOT_THEME
library_mastery:
score: 6
max: 10
items:
- id: LM-01
name: Idiomatic Usage
score: 4
max: 5
passed: true
comment: Uses ggplot/aes/geoms idiomatically; missing theme-adaptive chrome
pattern
- id: LM-02
name: Distinctive Features
score: 2
max: 5
passed: false
comment: geom_rect for custom shapes is appropriate but techniques are standard
verdict: APPROVED
impl_tags:
dependencies: []
techniques:
- annotations
patterns:
- data-generation
- matrix-construction
dataprep: []
styling:
- minimal-chrome
- edge-highlighting
strengths: []
weaknesses: []