|
1 | 1 | """ anyplot.ai |
2 | 2 | slope-basic: Basic Slope Chart (Slopegraph) |
3 | | -Library: pygal 3.1.0 | Python 3.13.13 |
4 | | -Quality: 86/100 | Updated: 2026-04-30 |
| 3 | +Library: pygal 3.1.3 | Python 3.13.14 |
| 4 | +Quality: 85/100 | Updated: 2026-07-25 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import os |
|
21 | 21 | INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
22 | 22 | INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" |
23 | 23 |
|
24 | | -COLOR_INCREASE = "#009E73" # Okabe-Ito position 1 — upward change |
25 | | -COLOR_DECREASE = "#AE3030" # imprint red — downward change |
| 24 | +COLOR_INCREASE = "#009E73" # Imprint palette position 1 — upward change |
| 25 | +COLOR_DECREASE = "#AE3030" # Imprint palette position 5 — semantic anchor for downward change |
26 | 26 |
|
27 | | -# Realistic product category data — Q1 vs Q4 sales comparison |
| 27 | +# Realistic product category data — Q1 vs Q4 sales comparison. |
| 28 | +# Values are spread with even 7/8-unit gaps within each quarter so the |
| 29 | +# endpoint category-name labels never crowd or overlap each other. |
28 | 30 | categories = [ |
29 | 31 | "Electronics", |
30 | 32 | "Apparel", |
|
37 | 39 | "Beauty", |
38 | 40 | "Toys", |
39 | 41 | ] |
40 | | -q1_sales = [85, 72, 95, 45, 68, 52, 78, 62, 88, 40] |
41 | | -q4_sales = [92, 58, 102, 75, 65, 71, 82, 48, 95, 55] |
| 42 | +q1_sales = [75, 82, 103, 40, 68, 47, 89, 61, 96, 54] |
| 43 | +q4_sales = [90, 58, 114, 74, 66, 82, 98, 42, 106, 50] |
42 | 44 |
|
43 | 45 | increasing = [(c, q1_sales[i], q4_sales[i]) for i, c in enumerate(categories) if q4_sales[i] >= q1_sales[i]] |
44 | 46 | decreasing = [(c, q1_sales[i], q4_sales[i]) for i, c in enumerate(categories) if q4_sales[i] < q1_sales[i]] |
|
52 | 54 | foreground_strong=INK, |
53 | 55 | foreground_subtle=INK_MUTED, |
54 | 56 | colors=series_colors, |
55 | | - title_font_size=64, |
56 | | - label_font_size=44, |
| 57 | + title_font_size=66, |
| 58 | + label_font_size=56, |
57 | 59 | major_label_font_size=44, |
58 | | - legend_font_size=38, |
59 | | - value_font_size=32, |
60 | | - value_label_font_size=36, |
| 60 | + value_label_font_size=44, |
| 61 | + # value_font_size drives pygal's dot-to-label offset (x/y = dot + value_font_size), |
| 62 | + # not just the (unused, print_values=False) value text itself — raised well past |
| 63 | + # the default 16 so category labels clear the y-axis line at the Q1 column. |
| 64 | + value_font_size=40, |
61 | 65 | stroke_width=6, |
62 | 66 | ) |
63 | 67 |
|
64 | | -# Slope chart: Line chart with only 2 x-axis time points |
| 68 | +# Slope chart: Line chart with only 2 x-axis time points. |
| 69 | +# The legend is omitted — each line already carries its category name at |
| 70 | +# both endpoints (print_labels), and the up/down direction is self-evident |
| 71 | +# from the slope itself, so a color legend would only duplicate that info. |
65 | 72 | chart = pygal.Line( |
66 | | - width=4800, |
67 | | - height=2700, |
68 | | - title="slope-basic · pygal · anyplot.ai", |
| 73 | + width=3200, |
| 74 | + height=1800, |
| 75 | + title="slope-basic · python · pygal · anyplot.ai", |
69 | 76 | x_title="Time Period", |
70 | | - y_title="Sales (units)", |
| 77 | + y_title="Sales (thousands of units)", |
71 | 78 | style=custom_style, |
72 | 79 | show_dots=True, |
73 | 80 | dots_size=18, |
74 | | - stroke_style={"width": 6}, |
75 | 81 | show_y_guides=True, |
76 | 82 | show_x_guides=False, |
77 | | - show_legend=True, |
| 83 | + show_legend=False, |
78 | 84 | interpolate=None, |
79 | 85 | margin=140, |
80 | 86 | print_values=False, |
81 | 87 | print_labels=True, |
82 | | - range=(30, 115), |
83 | | - margin_right=340, |
| 88 | + range=(30, 120), |
| 89 | + margin_right=480, |
84 | 90 | ) |
85 | 91 |
|
86 | 92 | chart.x_labels = ["Q1 2024", "Q4 2024"] |
87 | 93 |
|
88 | | -# Increasing categories — Okabe-Ito green |
| 94 | +# Increasing categories — Imprint brand green |
89 | 95 | for c, start, end in increasing: |
90 | 96 | chart.add(c, [{"value": start, "label": c}, {"value": end, "label": c}]) |
91 | 97 |
|
92 | | -# Decreasing categories — Okabe-Ito vermillion |
| 98 | +# Decreasing categories — Imprint matte red |
93 | 99 | for c, start, end in decreasing: |
94 | 100 | chart.add(c, [{"value": start, "label": c}, {"value": end, "label": c}]) |
95 | 101 |
|
|
0 commit comments