Skip to content

Commit f47c454

Browse files
feat(plotly): implement dumbbell-basic (#5417)
## Implementation: `dumbbell-basic` - python/plotly Implements the **python/plotly** version of `dumbbell-basic`. **File:** `plots/dumbbell-basic/implementations/python/plotly.py` **Parent Issue:** #945 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/24944963786)* --------- 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 d3bb5ea commit f47c454

2 files changed

Lines changed: 244 additions & 160 deletions

File tree

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
dumbbell-basic: Basic Dumbbell Chart
3-
Library: plotly 6.5.0 | Python 3.13.11
4-
Quality: 93/100 | Created: 2025-12-23
3+
Library: plotly 6.7.0 | Python 3.14.4
4+
Quality: 87/100 | Updated: 2026-04-26
55
"""
66

7+
import os
8+
79
import plotly.graph_objects as go
810

911

10-
# Data - Employee satisfaction scores before and after policy changes
12+
# Theme-adaptive chrome 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+
GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
19+
20+
# Okabe-Ito palette (theme-independent data colors)
21+
BEFORE_COLOR = "#009E73" # position 1 — first categorical series
22+
AFTER_COLOR = "#D55E00" # position 2 — second series
23+
24+
# Data — Employee satisfaction scores before and after policy changes.
25+
# Deterministic, hand-picked values (no RNG): one department (Legal) shows a
26+
# slight regression to demonstrate full data range including negative change.
1127
categories = [
1228
"Engineering",
1329
"Sales",
@@ -17,77 +33,97 @@
1733
"Human Resources",
1834
"Operations",
1935
"Product",
36+
"Legal",
2037
]
21-
before = [62, 71, 58, 45, 68, 52, 64, 73] # Before policy changes
22-
after = [78, 82, 75, 69, 74, 71, 79, 85] # After policy changes
38+
before = [62, 71, 58, 45, 68, 52, 64, 73, 70]
39+
after = [78, 82, 75, 69, 74, 71, 79, 85, 67]
2340

24-
# Sort by difference (largest improvement at top of chart)
41+
# Sort by difference (largest improvement at top, regression at bottom)
2542
data = sorted(zip(categories, before, after, strict=True), key=lambda x: x[2] - x[1])
2643
categories = [d[0] for d in data]
2744
before = [d[1] for d in data]
2845
after = [d[2] for d in data]
2946

30-
# Create figure
3147
fig = go.Figure()
3248

33-
# Add connecting lines (one per category)
49+
# Connecting lines (one per category)
3450
for i, cat in enumerate(categories):
3551
fig.add_trace(
3652
go.Scatter(
3753
x=[before[i], after[i]],
3854
y=[cat, cat],
3955
mode="lines",
40-
line={"color": "#999999", "width": 2},
56+
line={"color": INK_SOFT, "width": 2},
4157
showlegend=False,
4258
hoverinfo="skip",
4359
)
4460
)
4561

46-
# Add "Before" dots (Python Blue)
62+
# "Before" markers — Okabe-Ito green (brand)
4763
fig.add_trace(
4864
go.Scatter(
4965
x=before,
5066
y=categories,
5167
mode="markers",
52-
marker={"size": 18, "color": "#306998"},
68+
marker={"size": 18, "color": BEFORE_COLOR, "line": {"color": PAGE_BG, "width": 2}},
5369
name="Before",
54-
hovertemplate="<b>%{y}</b><br>Before: %{x}<extra></extra>",
70+
hovertemplate="<b>%{y}</b><br>Before: %{x}/100<extra></extra>",
5571
)
5672
)
5773

58-
# Add "After" dots (Python Yellow)
74+
# "After" markers — Okabe-Ito vermillion
5975
fig.add_trace(
6076
go.Scatter(
6177
x=after,
6278
y=categories,
6379
mode="markers",
64-
marker={"size": 18, "color": "#FFD43B"},
80+
marker={"size": 18, "color": AFTER_COLOR, "line": {"color": PAGE_BG, "width": 2}},
6581
name="After",
66-
hovertemplate="<b>%{y}</b><br>After: %{x}<extra></extra>",
82+
hovertemplate="<b>%{y}</b><br>After: %{x}/100<extra></extra>",
6783
)
6884
)
6985

70-
# Layout
7186
fig.update_layout(
7287
title={
7388
"text": "Employee Satisfaction · dumbbell-basic · plotly · pyplots.ai",
74-
"font": {"size": 28},
89+
"font": {"size": 28, "color": INK},
7590
"x": 0.5,
7691
"xanchor": "center",
7792
},
7893
xaxis={
79-
"title": {"text": "Satisfaction Score", "font": {"size": 22}},
80-
"tickfont": {"size": 18},
94+
"title": {"text": "Satisfaction Score (out of 100)", "font": {"size": 22, "color": INK}},
95+
"tickfont": {"size": 18, "color": INK_SOFT},
8196
"range": [35, 95],
82-
"gridcolor": "rgba(0,0,0,0.1)",
97+
"gridcolor": GRID,
98+
"gridwidth": 1,
99+
"linecolor": INK_SOFT,
100+
"zerolinecolor": INK_SOFT,
101+
},
102+
yaxis={
103+
"title": {"text": "Department", "font": {"size": 22, "color": INK}},
104+
"tickfont": {"size": 18, "color": INK_SOFT},
105+
"gridcolor": GRID,
83106
"gridwidth": 1,
107+
"linecolor": INK_SOFT,
108+
"zerolinecolor": INK_SOFT,
109+
"showgrid": True,
110+
},
111+
paper_bgcolor=PAGE_BG,
112+
plot_bgcolor=PAGE_BG,
113+
font={"color": INK},
114+
legend={
115+
"orientation": "h",
116+
"yanchor": "bottom",
117+
"y": 1.02,
118+
"xanchor": "center",
119+
"x": 0.5,
120+
"font": {"size": 16, "color": INK_SOFT},
121+
"bgcolor": ELEVATED_BG,
122+
"bordercolor": INK_SOFT,
123+
"borderwidth": 1,
84124
},
85-
yaxis={"title": {"text": "Department", "font": {"size": 22}}, "tickfont": {"size": 18}},
86-
template="plotly_white",
87-
legend={"orientation": "h", "yanchor": "bottom", "y": 1.02, "xanchor": "center", "x": 0.5, "font": {"size": 18}},
88-
margin={"l": 150, "r": 50, "t": 100, "b": 80},
125+
margin={"l": 170, "r": 60, "t": 110, "b": 90},
89126
)
90127

91-
# Save
92-
fig.write_image("plot.png", width=1600, height=900, scale=3)
93-
fig.write_html("plot.html", include_plotlyjs="cdn")
128+
fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3)
129+
fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn")

0 commit comments

Comments
 (0)