|
1 | 1 | """ pyplots.ai |
2 | 2 | bar-basic: Basic Bar 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 | +Quality: 88/100 | Created: 2025-12-23 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import pygal |
8 | 8 | from pygal.style import Style |
9 | 9 |
|
10 | 10 |
|
11 | | -# Data - Quarterly sales by product category |
12 | | -categories = ["Electronics", "Clothing", "Home & Garden", "Sports", "Books", "Toys"] |
13 | | -values = [45200, 32800, 28500, 19700, 15300, 12400] |
| 11 | +# Data - Quarterly website traffic by channel (non-monotonic for diversity) |
| 12 | +categories = ["Organic Search", "Direct", "Social Media", "Email", "Referral", "Paid Ads", "Affiliates"] |
| 13 | +values = [142500, 98700, 87300, 53200, 41800, 72600, 18900] |
14 | 14 |
|
15 | | -# Custom style using PyPlots color palette |
| 15 | +# Identify the leader for emphasis |
| 16 | +max_idx = values.index(max(values)) |
| 17 | +total = sum(values) |
| 18 | +highlight_color = "#306998" |
| 19 | +base_color = "#A8C4D8" |
| 20 | + |
| 21 | +# Build per-bar data — highlight leader, muted for the rest |
| 22 | +# Add percentage share as label for the leader bar to tell the data story |
| 23 | +bar_data = [] |
| 24 | +for i, v in enumerate(values): |
| 25 | + entry = {"value": v, "color": highlight_color if i == max_idx else base_color} |
| 26 | + if i == max_idx: |
| 27 | + entry["formatter"] = lambda x: f"★ {x:,.0f} ({x / total:.0%} of total)" |
| 28 | + bar_data.append(entry) |
| 29 | + |
| 30 | +# Custom style — refined for publication quality |
16 | 31 | custom_style = Style( |
17 | 32 | background="white", |
18 | 33 | plot_background="white", |
19 | | - foreground="#333333", |
20 | | - foreground_strong="#333333", |
21 | | - foreground_subtle="#666666", |
22 | | - colors=("#306998",), # Python Blue for all bars |
23 | | - title_font_size=48, |
24 | | - label_font_size=38, |
25 | | - major_label_font_size=38, |
| 34 | + foreground="#2C3E50", |
| 35 | + foreground_strong="#2C3E50", |
| 36 | + foreground_subtle="#E8E8E8", |
| 37 | + colors=(highlight_color,), |
| 38 | + title_font_size=52, |
| 39 | + label_font_size=34, |
| 40 | + major_label_font_size=34, |
26 | 41 | value_font_size=32, |
27 | 42 | value_label_font_size=32, |
28 | | - legend_font_size=38, |
| 43 | + legend_font_size=34, |
| 44 | + title_font_family="sans-serif", |
| 45 | + label_font_family="sans-serif", |
| 46 | + value_font_family="sans-serif", |
29 | 47 | ) |
30 | 48 |
|
31 | | -# Create chart |
| 49 | +# Create chart with tighter margins for better canvas utilization |
32 | 50 | chart = pygal.Bar( |
33 | 51 | width=4800, |
34 | 52 | height=2700, |
35 | | - title="bar-basic · pygal · pyplots.ai", |
36 | | - x_title="Category", |
37 | | - y_title="Sales ($)", |
| 53 | + title="bar-basic · pygal · pyplots.ai\nOrganic Search dominates Q4 2025 traffic at 28% share", |
| 54 | + x_title="Channel", |
| 55 | + y_title="Visits (Q4 2025)", |
38 | 56 | style=custom_style, |
39 | 57 | show_legend=False, |
40 | 58 | print_values=True, |
41 | 59 | print_values_position="top", |
42 | | - value_formatter=lambda x: f"${x:,.0f}", |
| 60 | + value_formatter=lambda x: f"{x:,.0f}", |
43 | 61 | show_y_guides=True, |
44 | 62 | show_x_guides=False, |
45 | | - margin=50, |
46 | | - spacing=30, |
| 63 | + margin=20, |
| 64 | + margin_bottom=80, |
| 65 | + margin_left=30, |
| 66 | + margin_right=30, |
| 67 | + spacing=18, |
| 68 | + rounded_bars=6, |
| 69 | + truncate_label=-1, |
| 70 | + x_label_rotation=0, |
| 71 | + show_minor_y_labels=False, |
| 72 | + y_labels_major_every=1, |
47 | 73 | ) |
48 | 74 |
|
| 75 | +# Y-axis ticks |
| 76 | +chart.y_labels = [0, 30000, 60000, 90000, 120000, 150000] |
| 77 | + |
49 | 78 | # Add data |
50 | 79 | chart.x_labels = categories |
51 | | -chart.add("Sales", values) |
| 80 | +chart.add("Visits", bar_data) |
52 | 81 |
|
53 | | -# Save outputs |
| 82 | +# Save |
54 | 83 | chart.render_to_png("plot.png") |
55 | | -chart.render_to_file("plot.html") |
|
0 commit comments