Skip to content

Commit d85b84d

Browse files
feat(altair): implement lollipop-basic (#5445)
## Implementation: `lollipop-basic` - python/altair Implements the **python/altair** version of `lollipop-basic`. **File:** `plots/lollipop-basic/implementations/python/altair.py` **Parent Issue:** #934 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/24956996445)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent a307c96 commit d85b84d

2 files changed

Lines changed: 209 additions & 151 deletions

File tree

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
lollipop-basic: Basic Lollipop Chart
3-
Library: altair 6.0.0 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: altair 6.1.0 | Python 3.14.4
4+
Quality: 91/100 | Updated: 2026-04-26
55
"""
66

7+
import os
8+
79
import altair as alt
810
import pandas as pd
911

1012

11-
# Data - Product sales by category, sorted by value
13+
# Theme tokens (see prompts/default-style-guide.md "Theme-adaptive Chrome")
14+
THEME = os.getenv("ANYPLOT_THEME", "light")
15+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
16+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
17+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
18+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
19+
GRID = INK
20+
GRID_OPACITY = 0.10
21+
22+
BRAND = "#009E73" # Okabe-Ito position 1 — ALWAYS first series
23+
24+
# Data — Product sales by category, sorted by value
1225
categories = [
1326
"Electronics",
1427
"Clothing",
@@ -24,45 +37,62 @@
2437
values = [425000, 312000, 287000, 234000, 198000, 176000, 152000, 134000, 118000, 95000]
2538

2639
df = pd.DataFrame({"category": categories, "value": values})
27-
28-
# Sort by value descending for better readability
2940
df = df.sort_values("value", ascending=False).reset_index(drop=True)
3041

31-
# Create stems (vertical lines from baseline to value)
42+
# Stems (vertical lines from baseline to value)
3243
stems = (
3344
alt.Chart(df)
34-
.mark_rule(color="#306998", strokeWidth=3)
45+
.mark_rule(color=BRAND, strokeWidth=4)
3546
.encode(
36-
x=alt.X(
37-
"category:N", sort="-y", title="Category", axis=alt.Axis(labelFontSize=16, titleFontSize=20, labelAngle=-45)
38-
),
39-
y=alt.Y("value:Q", title="Sales ($)", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
47+
x=alt.X("category:N", sort="-y", title="Category", axis=alt.Axis(labelAngle=-35)),
48+
y=alt.Y("value:Q", title="Sales (USD)", axis=alt.Axis(format="$,.0f")),
4049
)
4150
)
4251

43-
# Create dots at the top of each stem
52+
# Dots at the top of each stem
4453
dots = (
4554
alt.Chart(df)
46-
.mark_circle(color="#306998", size=400)
55+
.mark_circle(color=BRAND, size=550, opacity=1, stroke=PAGE_BG, strokeWidth=2)
4756
.encode(
4857
x=alt.X("category:N", sort="-y"),
4958
y=alt.Y("value:Q"),
50-
tooltip=["category:N", alt.Tooltip("value:Q", format="$,.0f")],
59+
tooltip=[alt.Tooltip("category:N", title="Category"), alt.Tooltip("value:Q", title="Sales", format="$,.0f")],
5160
)
5261
)
5362

54-
# Combine stems and dots
5563
chart = (
5664
(stems + dots)
5765
.properties(
58-
width=1600, height=900, title=alt.Title("lollipop-basic · altair · pyplots.ai", fontSize=28, anchor="middle")
66+
width=1600,
67+
height=900,
68+
background=PAGE_BG,
69+
title=alt.Title(
70+
"Product Sales by Category · lollipop-basic · altair · anyplot.ai",
71+
fontSize=28,
72+
anchor="start",
73+
color=INK,
74+
offset=20,
75+
),
5976
)
60-
.configure_axis(labelFontSize=16, titleFontSize=20, grid=True, gridOpacity=0.3)
61-
.configure_view(strokeWidth=0)
77+
.configure_view(fill=PAGE_BG, stroke=None)
78+
.configure_axis(
79+
domainColor=INK_SOFT,
80+
domainWidth=1,
81+
tickColor=INK_SOFT,
82+
gridColor=GRID,
83+
gridOpacity=GRID_OPACITY,
84+
gridWidth=1,
85+
labelColor=INK_SOFT,
86+
labelFontSize=18,
87+
titleColor=INK,
88+
titleFontSize=22,
89+
titlePadding=18,
90+
)
91+
.configure_axisX(grid=False, labelPadding=8)
92+
.configure_axisY(grid=True, labelPadding=8)
93+
.configure_title(color=INK, fontWeight="bold")
94+
.configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK)
6295
)
6396

64-
# Save as PNG (scale_factor=3 to get 4800x2700)
65-
chart.save("plot.png", scale_factor=3.0)
66-
67-
# Save as HTML for interactive version
68-
chart.save("plot.html")
97+
chart.save(f"plot-{THEME}.png", scale_factor=3.0)
98+
chart.save(f"plot-{THEME}.html")

0 commit comments

Comments
 (0)