Skip to content

Commit 057b250

Browse files
feat(pygal): implement gauge-basic (#5397)
## Implementation: `gauge-basic` - python/pygal Implements the **python/pygal** version of `gauge-basic`. **File:** `plots/gauge-basic/implementations/python/pygal.py` **Parent Issue:** #857 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/24931399741)* --------- 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 3d67d5f commit 057b250

2 files changed

Lines changed: 213 additions & 154 deletions

File tree

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,78 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
gauge-basic: Basic Gauge Chart
3-
Library: pygal 3.1.0 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: pygal 3.1.0 | Python 3.14.4
4+
Quality: 87/100 | Updated: 2026-04-25
55
"""
66

7-
import pygal
8-
from pygal.style import Style
7+
import os
8+
import sys
9+
from pathlib import Path
910

1011

11-
# Data - Current sales performance against target
12-
value = 72 # Current value to display
12+
# Remove script directory from path to avoid name collision with the pygal package
13+
_script_dir = str(Path(__file__).parent)
14+
sys.path = [p for p in sys.path if p != _script_dir]
15+
16+
import pygal # noqa: E402
17+
from pygal.style import Style # noqa: E402
18+
19+
20+
# Theme tokens
21+
THEME = os.getenv("ANYPLOT_THEME", "light")
22+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
23+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
24+
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
25+
26+
# Data — quarterly sales performance against an annual target
27+
value = 72
28+
min_value = 0
1329
max_value = 100
14-
# Thresholds: 0-30 = Poor (red), 30-70 = Fair (yellow), 70-100 = Good (green)
30+
thresholds = [30, 70]
31+
32+
# Semantic threshold colors using Okabe-Ito hues (bad → warn → good)
33+
ZONE_COLORS = ("#D55E00", "#E69F00", "#009E73")
1534

16-
# Determine zone color based on value position
17-
if value < 30:
18-
value_color = "#E74C3C" # Red for poor zone
19-
elif value < 70:
20-
value_color = "#F1C40F" # Yellow for fair zone
35+
if value < thresholds[0]:
36+
zone_label = "Poor"
37+
elif value < thresholds[1]:
38+
zone_label = "Fair"
2139
else:
22-
value_color = "#2ECC71" # Green for good zone
40+
zone_label = "Good"
2341

24-
# Custom style for 4800x2700 px with large fonts
2542
custom_style = Style(
26-
background="white",
27-
plot_background="white",
28-
foreground="#333333",
29-
foreground_strong="#1a1a1a",
30-
foreground_subtle="#666666",
31-
colors=(value_color,),
32-
title_font_size=72,
33-
label_font_size=54,
34-
major_label_font_size=54,
35-
legend_font_size=52,
36-
value_font_size=72,
43+
background=PAGE_BG,
44+
plot_background=PAGE_BG,
45+
foreground=INK,
46+
foreground_strong=INK,
47+
foreground_subtle=INK_MUTED,
48+
colors=ZONE_COLORS,
49+
title_font_size=64,
50+
label_font_size=44,
51+
major_label_font_size=44,
52+
legend_font_size=44,
53+
value_font_size=56,
3754
tooltip_font_size=40,
3855
)
3956

40-
# Create SolidGauge chart (semi-circular gauge)
41-
chart = pygal.SolidGauge(
57+
chart = pygal.Pie(
4258
width=4800,
4359
height=2700,
60+
title=f"Sales: {value}/{max_value} ({zone_label}) · gauge-basic · pygal · anyplot.ai",
4461
style=custom_style,
45-
title="Sales Performance · gauge-basic · pygal · pyplots.ai",
46-
inner_radius=0.60,
4762
half_pie=True,
63+
inner_radius=0.55,
4864
show_legend=True,
4965
legend_at_bottom=True,
50-
print_values=True,
51-
value_formatter=lambda x: f"{x:.0f}%",
52-
margin=100,
66+
print_values=False,
67+
margin=80,
5368
)
5469

55-
# Add single gauge showing current value against max
56-
# Value 72 is in the "Good" zone (70-100)
57-
chart.add(f"Current Sales: {value}% (Good Zone)", [{"value": value, "max_value": max_value}])
70+
# Threshold zones render as colored arcs of the semi-circular gauge
71+
chart.add(f"Poor ({min_value}{thresholds[0]})", thresholds[0] - min_value)
72+
chart.add(f"Fair ({thresholds[0]}{thresholds[1]})", thresholds[1] - thresholds[0])
73+
chart.add(f"Good ({thresholds[1]}{max_value}) — current: {value}", max_value - thresholds[1])
5874

59-
# Save outputs
60-
chart.render_to_png("plot.png")
61-
chart.render_to_file("plot.html")
75+
# Save
76+
chart.render_to_png(f"plot-{THEME}.png")
77+
with open(f"plot-{THEME}.html", "wb") as f:
78+
f.write(chart.render())

0 commit comments

Comments
 (0)