|
1 | | -""" pyplots.ai |
| 1 | +""" anyplot.ai |
2 | 2 | gauge-basic: Basic Gauge Chart |
3 | | -Library: plotly 6.5.0 | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-23 |
| 3 | +Library: plotly 6.7.0 | Python 3.14.4 |
| 4 | +Quality: 94/100 | Updated: 2026-04-25 |
5 | 5 | """ |
6 | 6 |
|
| 7 | +import os |
| 8 | + |
7 | 9 | import plotly.graph_objects as go |
8 | 10 |
|
9 | 11 |
|
10 | | -# Data - Sales performance against quarterly target |
11 | | -value = 72 # Current sales achievement percentage |
| 12 | +# Theme tokens |
| 13 | +THEME = os.getenv("ANYPLOT_THEME", "light") |
| 14 | +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
| 15 | +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" |
| 16 | +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
| 17 | +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
| 18 | +INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" |
| 19 | + |
| 20 | +# Okabe-Ito colorblind-safe stand-ins for the red/amber/green convention |
| 21 | +ZONE_LOW = "#D55E00" # vermillion (bad) |
| 22 | +ZONE_MID = "#E69F00" # orange (caution) |
| 23 | +ZONE_HIGH = "#009E73" # bluish green — Okabe-Ito brand (good) |
| 24 | + |
| 25 | +# Data — Sales target achievement for the quarter |
| 26 | +value = 72 |
12 | 27 | min_value = 0 |
13 | 28 | max_value = 100 |
14 | | -thresholds = [30, 70] # Red/Yellow/Green zones |
| 29 | +thresholds = [30, 70] |
15 | 30 |
|
16 | | -# Create gauge chart |
| 31 | +# Plot |
17 | 32 | fig = go.Figure( |
18 | 33 | go.Indicator( |
19 | 34 | mode="gauge+number", |
20 | 35 | value=value, |
| 36 | + number={"font": {"size": 96, "color": INK}, "suffix": "%"}, |
21 | 37 | title={ |
22 | | - "text": "Sales Target Achievement<br><span style='font-size:24px'>gauge-basic · plotly · pyplots.ai</span>", |
23 | | - "font": {"size": 32}, |
| 38 | + "text": ( |
| 39 | + "<b>Sales Target Achievement</b>" |
| 40 | + f"<br><span style='font-size:22px;color:{INK_SOFT}'>" |
| 41 | + "gauge-basic · plotly · anyplot.ai</span>" |
| 42 | + ), |
| 43 | + "font": {"size": 32, "color": INK}, |
24 | 44 | }, |
25 | | - number={"font": {"size": 72}, "suffix": "%"}, |
26 | 45 | gauge={ |
| 46 | + "shape": "angular", |
27 | 47 | "axis": { |
28 | 48 | "range": [min_value, max_value], |
29 | | - "tickwidth": 3, |
30 | | - "tickcolor": "#306998", |
31 | | - "tickfont": {"size": 22}, |
| 49 | + "tickwidth": 2, |
| 50 | + "tickcolor": INK_SOFT, |
| 51 | + "tickfont": {"size": 18, "color": INK_SOFT}, |
32 | 52 | "ticksuffix": "%", |
33 | 53 | "dtick": 10, |
34 | 54 | }, |
35 | | - "bar": {"color": "#306998", "thickness": 0.25}, |
36 | | - "bgcolor": "white", |
37 | | - "borderwidth": 3, |
38 | | - "bordercolor": "#306998", |
| 55 | + # Slim needle-style indicator so the zone colors stay visible |
| 56 | + "bar": {"color": INK, "thickness": 0.06, "line": {"color": INK, "width": 0}}, |
| 57 | + "bgcolor": ELEVATED_BG, |
| 58 | + "borderwidth": 1, |
| 59 | + "bordercolor": INK_SOFT, |
39 | 60 | "steps": [ |
40 | | - {"range": [min_value, thresholds[0]], "color": "#FF6B6B"}, |
41 | | - {"range": [thresholds[0], thresholds[1]], "color": "#FFD43B"}, |
42 | | - {"range": [thresholds[1], max_value], "color": "#4CAF50"}, |
| 61 | + {"range": [min_value, thresholds[0]], "color": ZONE_LOW}, |
| 62 | + {"range": [thresholds[0], thresholds[1]], "color": ZONE_MID}, |
| 63 | + {"range": [thresholds[1], max_value], "color": ZONE_HIGH}, |
43 | 64 | ], |
44 | | - "threshold": {"line": {"color": "#306998", "width": 8}, "thickness": 0.85, "value": value}, |
| 65 | + "threshold": {"line": {"color": INK, "width": 5}, "thickness": 0.95, "value": value}, |
45 | 66 | }, |
46 | | - domain={"x": [0.05, 0.95], "y": [0.1, 0.95]}, |
| 67 | + domain={"x": [0.05, 0.95], "y": [0.30, 0.95]}, |
47 | 68 | ) |
48 | 69 | ) |
49 | 70 |
|
50 | | -# Layout for 4800x2700 px |
| 71 | +# Layout — page surface + zone legend + target-exceeded callout |
51 | 72 | fig.update_layout( |
52 | | - font={"family": "Arial", "size": 22}, |
53 | | - paper_bgcolor="white", |
54 | | - plot_bgcolor="white", |
55 | | - margin={"l": 80, "r": 80, "t": 120, "b": 60}, |
| 73 | + paper_bgcolor=PAGE_BG, |
| 74 | + plot_bgcolor=PAGE_BG, |
| 75 | + font={"family": "Arial", "color": INK}, |
| 76 | + margin={"l": 80, "r": 80, "t": 140, "b": 120}, |
| 77 | + annotations=[ |
| 78 | + # Zone legend row — three color-coded chips below the gauge |
| 79 | + { |
| 80 | + "x": 0.20, |
| 81 | + "y": 0.14, |
| 82 | + "xref": "paper", |
| 83 | + "yref": "paper", |
| 84 | + "text": ( |
| 85 | + f"<span style='color:{ZONE_LOW};font-size:24px'>●</span> " |
| 86 | + f"<b>At Risk</b> " |
| 87 | + f"<span style='color:{INK_MUTED}'>0–30%</span>" |
| 88 | + ), |
| 89 | + "showarrow": False, |
| 90 | + "font": {"size": 18, "color": INK}, |
| 91 | + }, |
| 92 | + { |
| 93 | + "x": 0.50, |
| 94 | + "y": 0.14, |
| 95 | + "xref": "paper", |
| 96 | + "yref": "paper", |
| 97 | + "text": ( |
| 98 | + f"<span style='color:{ZONE_MID};font-size:24px'>●</span> " |
| 99 | + f"<b>On Track</b> " |
| 100 | + f"<span style='color:{INK_MUTED}'>30–70%</span>" |
| 101 | + ), |
| 102 | + "showarrow": False, |
| 103 | + "font": {"size": 18, "color": INK}, |
| 104 | + }, |
| 105 | + { |
| 106 | + "x": 0.80, |
| 107 | + "y": 0.14, |
| 108 | + "xref": "paper", |
| 109 | + "yref": "paper", |
| 110 | + "text": ( |
| 111 | + f"<span style='color:{ZONE_HIGH};font-size:24px'>●</span> " |
| 112 | + f"<b>Exceeds Target</b> " |
| 113 | + f"<span style='color:{INK_MUTED}'>70–100%</span>" |
| 114 | + ), |
| 115 | + "showarrow": False, |
| 116 | + "font": {"size": 18, "color": INK}, |
| 117 | + }, |
| 118 | + # Target-exceeded callout — emphasises the threshold-crossing story |
| 119 | + { |
| 120 | + "x": 0.5, |
| 121 | + "y": 0.02, |
| 122 | + "xref": "paper", |
| 123 | + "yref": "paper", |
| 124 | + "text": "<b>✓ Target Exceeded</b> · 72% surpasses the 70% goal", |
| 125 | + "showarrow": False, |
| 126 | + "font": {"size": 22, "color": ZONE_HIGH}, |
| 127 | + "bgcolor": ELEVATED_BG, |
| 128 | + "bordercolor": ZONE_HIGH, |
| 129 | + "borderwidth": 2, |
| 130 | + "borderpad": 12, |
| 131 | + }, |
| 132 | + ], |
56 | 133 | ) |
57 | 134 |
|
58 | | -# Save as PNG and HTML |
59 | | -fig.write_image("plot.png", width=1600, height=900, scale=3) |
60 | | -fig.write_html("plot.html") |
| 135 | +# Save |
| 136 | +fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3) |
| 137 | +fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn") |
0 commit comments