From 6a102139204f81a3cf8649dd90d126729b741fd0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 21:52:17 +0000 Subject: [PATCH 1/7] feat(plotnine): implement icicle-basic --- .../icicle-basic/implementations/plotnine.py | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 plots/icicle-basic/implementations/plotnine.py diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py new file mode 100644 index 0000000000..dc1e4d8699 --- /dev/null +++ b/plots/icicle-basic/implementations/plotnine.py @@ -0,0 +1,154 @@ +"""pyplots.ai +icicle-basic: Basic Icicle Chart +Library: plotnine | Python 3.13 +Quality: pending | Created: 2025-12-30 +""" + +import pandas as pd +from plotnine import aes, element_text, geom_rect, geom_text, ggplot, labs, scale_fill_manual, theme, theme_void + + +# Data: File system hierarchy with sizes +data = [ + {"name": "root", "parent": "", "value": 0}, + {"name": "Documents", "parent": "root", "value": 0}, + {"name": "Photos", "parent": "root", "value": 0}, + {"name": "Projects", "parent": "root", "value": 0}, + {"name": "Reports", "parent": "Documents", "value": 450}, + {"name": "Invoices", "parent": "Documents", "value": 280}, + {"name": "Notes", "parent": "Documents", "value": 120}, + {"name": "Vacation", "parent": "Photos", "value": 680}, + {"name": "Family", "parent": "Photos", "value": 520}, + {"name": "Events", "parent": "Photos", "value": 340}, + {"name": "WebApp", "parent": "Projects", "value": 0}, + {"name": "DataSci", "parent": "Projects", "value": 0}, + {"name": "Mobile", "parent": "Projects", "value": 380}, + {"name": "Frontend", "parent": "WebApp", "value": 290}, + {"name": "Backend", "parent": "WebApp", "value": 410}, + {"name": "Config", "parent": "WebApp", "value": 85}, + {"name": "Models", "parent": "DataSci", "value": 520}, + {"name": "Scripts", "parent": "DataSci", "value": 180}, +] + +df = pd.DataFrame(data) + + +# Build hierarchy and calculate sizes (leaf-up aggregation) +def calculate_values(df): + """Calculate values for non-leaf nodes by summing children.""" + result = df.copy() + name_to_idx = {row["name"]: idx for idx, row in result.iterrows()} + + # Recursive function to get total value + def get_total(name): + idx = name_to_idx[name] + children = result[result["parent"] == name] + if len(children) == 0: + return result.loc[idx, "value"] + total = sum(get_total(child) for child in children["name"]) + result.loc[idx, "value"] = total + return total + + get_total("root") + return result + + +df = calculate_values(df) + + +# Calculate icicle layout (horizontal: root at top, children below) +def compute_icicle_layout(df): + """Compute rectangle positions for icicle chart.""" + name_to_row = {row["name"]: row for _, row in df.iterrows()} + + # Assign depth levels + depths = {} + + def get_depth(name): + if name in depths: + return depths[name] + row = name_to_row.get(name) + if row is None or row["parent"] == "": + depths[name] = 0 + return 0 + depths[name] = get_depth(row["parent"]) + 1 + return depths[name] + + for name in df["name"]: + get_depth(name) + + max_depth = max(depths.values()) + + # Layout: rectangles based on value proportion + rects = [] + + def layout_node(name, x_start, x_end): + row = name_to_row[name] + depth = depths[name] + y_top = max_depth - depth + 1 + y_bottom = max_depth - depth + + rects.append( + { + "name": name, + "xmin": x_start, + "xmax": x_end, + "ymin": y_bottom, + "ymax": y_top, + "depth": depth, + "value": row["value"], + } + ) + + # Layout children + children = df[df["parent"] == name].sort_values("value", ascending=False) + if len(children) > 0: + total_value = children["value"].sum() + if total_value > 0: + curr_x = x_start + for _, child in children.iterrows(): + width = (child["value"] / total_value) * (x_end - x_start) + layout_node(child["name"], curr_x, curr_x + width) + curr_x += width + + layout_node("root", 0, 1) + return pd.DataFrame(rects) + + +rect_df = compute_icicle_layout(df) + +# Color palette by depth level +colors = { + 0: "#306998", # Python Blue - root + 1: "#4B8BBE", # Lighter blue - level 1 + 2: "#FFD43B", # Python Yellow - level 2 + 3: "#FFE873", # Light yellow - level 3 + 4: "#646464", # Gray - level 4 +} +rect_df["color"] = rect_df["depth"].map(colors) + +# Add labels only for rectangles wide enough +rect_df["width"] = rect_df["xmax"] - rect_df["xmin"] +rect_df["label"] = rect_df.apply(lambda r: r["name"] if r["width"] > 0.05 else "", axis=1) +rect_df["x_center"] = (rect_df["xmin"] + rect_df["xmax"]) / 2 +rect_df["y_center"] = (rect_df["ymin"] + rect_df["ymax"]) / 2 + +# Create plot +plot = ( + ggplot(rect_df) + + geom_rect(aes(xmin="xmin", xmax="xmax", ymin="ymin", ymax="ymax", fill="factor(depth)"), color="white", size=1.5) + + geom_text(aes(x="x_center", y="y_center", label="label"), size=12, color="black", fontweight="bold") + + scale_fill_manual(values=["#306998", "#4B8BBE", "#FFD43B", "#FFE873", "#90B4CE"], name="Hierarchy Level") + + labs(title="icicle-basic · plotnine · pyplots.ai") + + theme_void() + + theme( + figure_size=(16, 9), + plot_title=element_text(size=28, ha="center", weight="bold"), + legend_position="right", + legend_title=element_text(size=18), + legend_text=element_text(size=14), + ) +) + +# Save +plot.save("plot.png", dpi=300, verbose=False) From 7581adcc03fd08f3df23235272acf32effaeadd8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 21:52:32 +0000 Subject: [PATCH 2/7] chore(plotnine): add metadata for icicle-basic --- plots/icicle-basic/metadata/plotnine.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plots/icicle-basic/metadata/plotnine.yaml diff --git a/plots/icicle-basic/metadata/plotnine.yaml b/plots/icicle-basic/metadata/plotnine.yaml new file mode 100644 index 0000000000..bdee228d67 --- /dev/null +++ b/plots/icicle-basic/metadata/plotnine.yaml @@ -0,0 +1,19 @@ +# Per-library metadata for plotnine implementation of icicle-basic +# Auto-generated by impl-generate.yml + +library: plotnine +specification_id: icicle-basic +created: '2025-12-30T21:52:31Z' +updated: '2025-12-30T21:52:31Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20606631356 +issue: 0 +python_version: 3.13.11 +library_version: 0.15.2 +preview_url: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot_thumb.png +preview_html: null +quality_score: null +review: + strengths: [] + weaknesses: [] From 4a676c34ae88b1825f448c8f1f2b6a82665df728 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 21:54:43 +0000 Subject: [PATCH 3/7] chore(plotnine): update quality score 82 and review feedback for icicle-basic --- .../icicle-basic/implementations/plotnine.py | 6 ++--- plots/icicle-basic/metadata/plotnine.yaml | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py index dc1e4d8699..e3728a4f39 100644 --- a/plots/icicle-basic/implementations/plotnine.py +++ b/plots/icicle-basic/implementations/plotnine.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai icicle-basic: Basic Icicle Chart -Library: plotnine | Python 3.13 -Quality: pending | Created: 2025-12-30 +Library: plotnine 0.15.2 | Python 3.13.11 +Quality: 82/100 | Created: 2025-12-30 """ import pandas as pd diff --git a/plots/icicle-basic/metadata/plotnine.yaml b/plots/icicle-basic/metadata/plotnine.yaml index bdee228d67..6ebbadf3a2 100644 --- a/plots/icicle-basic/metadata/plotnine.yaml +++ b/plots/icicle-basic/metadata/plotnine.yaml @@ -1,10 +1,7 @@ -# Per-library metadata for plotnine implementation of icicle-basic -# Auto-generated by impl-generate.yml - library: plotnine specification_id: icicle-basic created: '2025-12-30T21:52:31Z' -updated: '2025-12-30T21:52:31Z' +updated: '2025-12-30T21:54:43Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20606631356 issue: 0 @@ -13,7 +10,20 @@ library_version: 0.15.2 preview_url: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot_thumb.png preview_html: null -quality_score: null +quality_score: 82 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent visual hierarchy with clear parent-child relationships through spatial + adjacency + - Smart label hiding for small rectangles prevents text overlap + - Realistic file system example matches spec applications perfectly + - Clean color progression by hierarchy level using Python-inspired blue/yellow palette + - Proper use of plotnine grammar of graphics (geom_rect, geom_text, theme_void) + weaknesses: + - Code uses helper functions (calculate_values, compute_icicle_layout) instead of + inline KISS structure + - 'Levels 2 and 3 yellow colors (#FFD43B and #FFE873) are too similar to distinguish + easily' + - Missing value/size annotations on rectangles would help users understand proportional + sizing + - Some leaf nodes (Config, Scripts, Notes) are invisible due to narrow width threshold From 052f0f03a9048f1b27ab715b67e2a1aa95cee47c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 21:58:25 +0000 Subject: [PATCH 4/7] fix(plotnine): address review feedback for icicle-basic - Replace helper functions with inline iterative loops (KISS structure) - Change level 3 color from light yellow to SaddleBrown for better distinction - Add value annotations (MB) to rectangle labels - Increase small node values and lower visibility threshold for all nodes visible Attempt 1/3 - fixes based on AI review --- .../icicle-basic/implementations/plotnine.py | 192 +++++++++--------- 1 file changed, 92 insertions(+), 100 deletions(-) diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py index e3728a4f39..d2c40aaf67 100644 --- a/plots/icicle-basic/implementations/plotnine.py +++ b/plots/icicle-basic/implementations/plotnine.py @@ -1,4 +1,4 @@ -""" pyplots.ai +"""pyplots.ai icicle-basic: Basic Icicle Chart Library: plotnine 0.15.2 | Python 3.13.11 Quality: 82/100 | Created: 2025-12-30 @@ -8,7 +8,8 @@ from plotnine import aes, element_text, geom_rect, geom_text, ggplot, labs, scale_fill_manual, theme, theme_void -# Data: File system hierarchy with sizes +# Data: File system hierarchy with sizes (MB) +# Increased small node values to ensure visibility data = [ {"name": "root", "parent": "", "value": 0}, {"name": "Documents", "parent": "root", "value": 0}, @@ -16,129 +17,120 @@ {"name": "Projects", "parent": "root", "value": 0}, {"name": "Reports", "parent": "Documents", "value": 450}, {"name": "Invoices", "parent": "Documents", "value": 280}, - {"name": "Notes", "parent": "Documents", "value": 120}, + {"name": "Notes", "parent": "Documents", "value": 180}, {"name": "Vacation", "parent": "Photos", "value": 680}, {"name": "Family", "parent": "Photos", "value": 520}, {"name": "Events", "parent": "Photos", "value": 340}, {"name": "WebApp", "parent": "Projects", "value": 0}, {"name": "DataSci", "parent": "Projects", "value": 0}, {"name": "Mobile", "parent": "Projects", "value": 380}, - {"name": "Frontend", "parent": "WebApp", "value": 290}, - {"name": "Backend", "parent": "WebApp", "value": 410}, - {"name": "Config", "parent": "WebApp", "value": 85}, + {"name": "Frontend", "parent": "WebApp", "value": 320}, + {"name": "Backend", "parent": "WebApp", "value": 420}, + {"name": "Config", "parent": "WebApp", "value": 200}, {"name": "Models", "parent": "DataSci", "value": 520}, - {"name": "Scripts", "parent": "DataSci", "value": 180}, + {"name": "Scripts", "parent": "DataSci", "value": 300}, ] df = pd.DataFrame(data) +# Build lookup tables +name_to_idx = {row["name"]: idx for idx, row in df.iterrows()} +children_map = {name: df[df["parent"] == name]["name"].tolist() for name in df["name"]} + +# Calculate values for non-leaf nodes (bottom-up aggregation) +# Process nodes from leaves up using iterative approach +processed = set() +while len(processed) < len(df): + for _, row in df.iterrows(): + name = row["name"] + if name in processed: + continue + kids = children_map[name] + if len(kids) == 0: + processed.add(name) + elif all(k in processed for k in kids): + total = sum(df.loc[name_to_idx[k], "value"] for k in kids) + df.loc[name_to_idx[name], "value"] = total + processed.add(name) + +# Calculate depths (distance from root) +depths = {"root": 0} +queue = ["root"] +while queue: + current = queue.pop(0) + for child in children_map[current]: + depths[child] = depths[current] + 1 + queue.append(child) + +max_depth = max(depths.values()) + +# Build icicle rectangles using iterative BFS +rects = [] +# Queue: (name, x_start, x_end) +layout_queue = [("root", 0.0, 1.0)] + +while layout_queue: + name, x_start, x_end = layout_queue.pop(0) + depth = depths[name] + y_top = max_depth - depth + 1 + y_bottom = max_depth - depth + value = df.loc[name_to_idx[name], "value"] + + rects.append( + {"name": name, "xmin": x_start, "xmax": x_end, "ymin": y_bottom, "ymax": y_top, "depth": depth, "value": value} + ) -# Build hierarchy and calculate sizes (leaf-up aggregation) -def calculate_values(df): - """Calculate values for non-leaf nodes by summing children.""" - result = df.copy() - name_to_idx = {row["name"]: idx for idx, row in result.iterrows()} - - # Recursive function to get total value - def get_total(name): - idx = name_to_idx[name] - children = result[result["parent"] == name] - if len(children) == 0: - return result.loc[idx, "value"] - total = sum(get_total(child) for child in children["name"]) - result.loc[idx, "value"] = total - return total - - get_total("root") - return result - - -df = calculate_values(df) - - -# Calculate icicle layout (horizontal: root at top, children below) -def compute_icicle_layout(df): - """Compute rectangle positions for icicle chart.""" - name_to_row = {row["name"]: row for _, row in df.iterrows()} - - # Assign depth levels - depths = {} - - def get_depth(name): - if name in depths: - return depths[name] - row = name_to_row.get(name) - if row is None or row["parent"] == "": - depths[name] = 0 - return 0 - depths[name] = get_depth(row["parent"]) + 1 - return depths[name] - - for name in df["name"]: - get_depth(name) - - max_depth = max(depths.values()) - - # Layout: rectangles based on value proportion - rects = [] - - def layout_node(name, x_start, x_end): - row = name_to_row[name] - depth = depths[name] - y_top = max_depth - depth + 1 - y_bottom = max_depth - depth - - rects.append( - { - "name": name, - "xmin": x_start, - "xmax": x_end, - "ymin": y_bottom, - "ymax": y_top, - "depth": depth, - "value": row["value"], - } - ) - - # Layout children - children = df[df["parent"] == name].sort_values("value", ascending=False) - if len(children) > 0: - total_value = children["value"].sum() - if total_value > 0: - curr_x = x_start - for _, child in children.iterrows(): - width = (child["value"] / total_value) * (x_end - x_start) - layout_node(child["name"], curr_x, curr_x + width) - curr_x += width - - layout_node("root", 0, 1) - return pd.DataFrame(rects) - - -rect_df = compute_icicle_layout(df) - -# Color palette by depth level + # Queue children proportionally + kids = children_map[name] + if kids: + kid_values = [(k, df.loc[name_to_idx[k], "value"]) for k in kids] + kid_values.sort(key=lambda x: -x[1]) # Sort by value descending + total_value = sum(v for _, v in kid_values) + if total_value > 0: + curr_x = x_start + for kid, val in kid_values: + width = (val / total_value) * (x_end - x_start) + layout_queue.append((kid, curr_x, curr_x + width)) + curr_x += width + +rect_df = pd.DataFrame(rects) + +# Color palette by depth - using distinct colors (fixed yellow similarity issue) colors = { 0: "#306998", # Python Blue - root 1: "#4B8BBE", # Lighter blue - level 1 2: "#FFD43B", # Python Yellow - level 2 - 3: "#FFE873", # Light yellow - level 3 - 4: "#646464", # Gray - level 4 + 3: "#8B4513", # SaddleBrown - level 3 (distinct from yellow) + 4: "#90B4CE", # Light steel blue - level 4 } -rect_df["color"] = rect_df["depth"].map(colors) +rect_df["fill_color"] = rect_df["depth"].map(colors) -# Add labels only for rectangles wide enough +# Calculate label positions and widths rect_df["width"] = rect_df["xmax"] - rect_df["xmin"] -rect_df["label"] = rect_df.apply(lambda r: r["name"] if r["width"] > 0.05 else "", axis=1) rect_df["x_center"] = (rect_df["xmin"] + rect_df["xmax"]) / 2 rect_df["y_center"] = (rect_df["ymin"] + rect_df["ymax"]) / 2 -# Create plot +# Labels: show name + value for wide rectangles, name only for medium, hide for very narrow +rect_df["label"] = rect_df.apply( + lambda r: f"{r['name']}\n({int(r['value'])} MB)" + if r["width"] > 0.08 + else (r["name"] if r["width"] > 0.025 else ""), + axis=1, +) + +# Separate dataframes for text coloring (white on dark, black on light) +dark_bg = rect_df[rect_df["depth"].isin([0, 1, 3])] +light_bg = rect_df[rect_df["depth"].isin([2, 4])] + +# Create plot using plotnine grammar of graphics plot = ( ggplot(rect_df) + geom_rect(aes(xmin="xmin", xmax="xmax", ymin="ymin", ymax="ymax", fill="factor(depth)"), color="white", size=1.5) - + geom_text(aes(x="x_center", y="y_center", label="label"), size=12, color="black", fontweight="bold") - + scale_fill_manual(values=["#306998", "#4B8BBE", "#FFD43B", "#FFE873", "#90B4CE"], name="Hierarchy Level") + + geom_text(aes(x="x_center", y="y_center", label="label"), data=dark_bg, size=11, color="white", fontweight="bold") + + geom_text( + aes(x="x_center", y="y_center", label="label"), data=light_bg, size=11, color="black", fontweight="bold" + ) + + scale_fill_manual(values=["#306998", "#4B8BBE", "#FFD43B", "#8B4513", "#90B4CE"], name="Hierarchy Level") + labs(title="icicle-basic · plotnine · pyplots.ai") + theme_void() + theme( From 7e857156d5e72b1575940a17b0deea1d8a51ad40 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 22:00:59 +0000 Subject: [PATCH 5/7] chore(plotnine): update quality score 88 and review feedback for icicle-basic --- .../icicle-basic/implementations/plotnine.py | 4 +-- plots/icicle-basic/metadata/plotnine.yaml | 28 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py index d2c40aaf67..debb0ef24a 100644 --- a/plots/icicle-basic/implementations/plotnine.py +++ b/plots/icicle-basic/implementations/plotnine.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai icicle-basic: Basic Icicle Chart Library: plotnine 0.15.2 | Python 3.13.11 -Quality: 82/100 | Created: 2025-12-30 +Quality: 88/100 | Created: 2025-12-30 """ import pandas as pd diff --git a/plots/icicle-basic/metadata/plotnine.yaml b/plots/icicle-basic/metadata/plotnine.yaml index 6ebbadf3a2..34c3de1829 100644 --- a/plots/icicle-basic/metadata/plotnine.yaml +++ b/plots/icicle-basic/metadata/plotnine.yaml @@ -1,7 +1,7 @@ library: plotnine specification_id: icicle-basic created: '2025-12-30T21:52:31Z' -updated: '2025-12-30T21:54:43Z' +updated: '2025-12-30T22:00:59Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20606631356 issue: 0 @@ -10,20 +10,18 @@ library_version: 0.15.2 preview_url: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot_thumb.png preview_html: null -quality_score: 82 +quality_score: 88 review: strengths: - - Excellent visual hierarchy with clear parent-child relationships through spatial - adjacency - - Smart label hiding for small rectangles prevents text overlap - - Realistic file system example matches spec applications perfectly - - Clean color progression by hierarchy level using Python-inspired blue/yellow palette - - Proper use of plotnine grammar of graphics (geom_rect, geom_text, theme_void) + - Excellent hierarchical structure with clear parent-child relationships through + spatial adjacency + - Smart text coloring (white on dark backgrounds, black on light) improves readability + - Appropriate use of plotnine grammar of graphics with geom_rect and geom_text + - Clean color palette with Python-branded blues and distinct hierarchy levels + - Good adaptive labeling that shows name+value for wide rectangles and hides labels + for narrow ones weaknesses: - - Code uses helper functions (calculate_values, compute_icicle_layout) instead of - inline KISS structure - - 'Levels 2 and 3 yellow colors (#FFD43B and #FFE873) are too similar to distinguish - easily' - - Missing value/size annotations on rectangles would help users understand proportional - sizing - - Some leaf nodes (Config, Scripts, Notes) are invisible due to narrow width threshold + - Legend shows only levels 0-3 but the chart includes level 4 nodes (brown rectangles + like Backend, Frontend, etc.) + - Some leaf-level labels are truncated (Frontend, Config show only names, no MB + values) while similar-width rectangles elsewhere show both From 722ce0e6fe1c5f987012e3212deea47d59d3572c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 22:04:16 +0000 Subject: [PATCH 6/7] fix(plotnine): address review feedback for icicle-basic Attempt 2/3 - fixes based on AI review: - Fixed legend to include all 5 hierarchy levels (0-4) with descriptive labels - Lowered label width threshold from 0.08 to 0.05 to ensure more nodes show MB values - Level labels now explicitly named: "Level 0 (Root)", "Level 1", etc. --- .../icicle-basic/implementations/plotnine.py | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py index debb0ef24a..c61f9e26ae 100644 --- a/plots/icicle-basic/implementations/plotnine.py +++ b/plots/icicle-basic/implementations/plotnine.py @@ -1,4 +1,4 @@ -""" pyplots.ai +"""pyplots.ai icicle-basic: Basic Icicle Chart Library: plotnine 0.15.2 | Python 3.13.11 Quality: 88/100 | Created: 2025-12-30 @@ -111,26 +111,40 @@ rect_df["y_center"] = (rect_df["ymin"] + rect_df["ymax"]) / 2 # Labels: show name + value for wide rectangles, name only for medium, hide for very narrow +# Lowered threshold to ensure more labels show value (fix for truncated labels) rect_df["label"] = rect_df.apply( - lambda r: f"{r['name']}\n({int(r['value'])} MB)" - if r["width"] > 0.08 - else (r["name"] if r["width"] > 0.025 else ""), + lambda r: f"{r['name']}\n({int(r['value'])} MB)" if r["width"] > 0.05 else (r["name"] if r["width"] > 0.02 else ""), axis=1, ) -# Separate dataframes for text coloring (white on dark, black on light) +# Convert depth to categorical with proper labels for legend +level_labels = {0: "Level 0 (Root)", 1: "Level 1", 2: "Level 2", 3: "Level 3", 4: "Level 4 (Leaf)"} +rect_df["depth_label"] = pd.Categorical( + rect_df["depth"].map(level_labels), categories=list(level_labels.values()), ordered=True +) + +# Also update dark_bg and light_bg with labels dark_bg = rect_df[rect_df["depth"].isin([0, 1, 3])] light_bg = rect_df[rect_df["depth"].isin([2, 4])] # Create plot using plotnine grammar of graphics plot = ( ggplot(rect_df) - + geom_rect(aes(xmin="xmin", xmax="xmax", ymin="ymin", ymax="ymax", fill="factor(depth)"), color="white", size=1.5) + + geom_rect(aes(xmin="xmin", xmax="xmax", ymin="ymin", ymax="ymax", fill="depth_label"), color="white", size=1.5) + geom_text(aes(x="x_center", y="y_center", label="label"), data=dark_bg, size=11, color="white", fontweight="bold") + geom_text( aes(x="x_center", y="y_center", label="label"), data=light_bg, size=11, color="black", fontweight="bold" ) - + scale_fill_manual(values=["#306998", "#4B8BBE", "#FFD43B", "#8B4513", "#90B4CE"], name="Hierarchy Level") + + scale_fill_manual( + values={ + "Level 0 (Root)": "#306998", + "Level 1": "#4B8BBE", + "Level 2": "#FFD43B", + "Level 3": "#8B4513", + "Level 4 (Leaf)": "#90B4CE", + }, + name="Hierarchy Level", + ) + labs(title="icicle-basic · plotnine · pyplots.ai") + theme_void() + theme( From 2ca40201aa511d2724855af3ac890966baf3369e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Dec 2025 22:06:37 +0000 Subject: [PATCH 7/7] chore(plotnine): update quality score 91 and review feedback for icicle-basic --- .../icicle-basic/implementations/plotnine.py | 4 +-- plots/icicle-basic/metadata/plotnine.yaml | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plots/icicle-basic/implementations/plotnine.py b/plots/icicle-basic/implementations/plotnine.py index c61f9e26ae..b8d6828777 100644 --- a/plots/icicle-basic/implementations/plotnine.py +++ b/plots/icicle-basic/implementations/plotnine.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai icicle-basic: Basic Icicle Chart Library: plotnine 0.15.2 | Python 3.13.11 -Quality: 88/100 | Created: 2025-12-30 +Quality: 91/100 | Created: 2025-12-30 """ import pandas as pd diff --git a/plots/icicle-basic/metadata/plotnine.yaml b/plots/icicle-basic/metadata/plotnine.yaml index 34c3de1829..6b7024676d 100644 --- a/plots/icicle-basic/metadata/plotnine.yaml +++ b/plots/icicle-basic/metadata/plotnine.yaml @@ -1,7 +1,7 @@ library: plotnine specification_id: icicle-basic created: '2025-12-30T21:52:31Z' -updated: '2025-12-30T22:00:59Z' +updated: '2025-12-30T22:06:37Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20606631356 issue: 0 @@ -10,18 +10,18 @@ library_version: 0.15.2 preview_url: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/icicle-basic/plotnine/plot_thumb.png preview_html: null -quality_score: 88 +quality_score: 91 review: strengths: - - Excellent hierarchical structure with clear parent-child relationships through - spatial adjacency - - Smart text coloring (white on dark backgrounds, black on light) improves readability - - Appropriate use of plotnine grammar of graphics with geom_rect and geom_text - - Clean color palette with Python-branded blues and distinct hierarchy levels - - Good adaptive labeling that shows name+value for wide rectangles and hides labels - for narrow ones + - Excellent hierarchical visualization with clear parent-child relationships visible + through spatial adjacency + - 'Smart label handling: shows name+value for wide rectangles, name-only for medium, + hidden for narrow' + - Good color contrast between hierarchy levels with appropriate text colors (white + on dark, black on light) + - Proper bottom-up value aggregation for non-leaf nodes + - Clean theme_void usage appropriate for this chart type + - Well-implemented BFS algorithm for layout calculation weaknesses: - - Legend shows only levels 0-3 but the chart includes level 4 nodes (brown rectangles - like Backend, Frontend, etc.) - - Some leaf-level labels are truncated (Frontend, Config show only names, no MB - values) while similar-width rectangles elsewhere show both + - Legend shows Hierarchy Level with just numbers 0-3 instead of the more descriptive + labels defined in the code