Skip to content

Commit 2460936

Browse files
feat(plotly): implement slope-basic (#5638)
## Implementation: `slope-basic` - python/plotly Implements the **python/plotly** version of `slope-basic`. **File:** `plots/slope-basic/implementations/python/plotly.py` **Parent Issue:** #981 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25177301713)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
1 parent 755bfd0 commit 2460936

2 files changed

Lines changed: 207 additions & 160 deletions

File tree

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
slope-basic: Basic Slope Chart (Slopegraph)
3-
Library: plotly 6.5.0 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: plotly 6.7.0 | Python 3.13.13
4+
Quality: 88/100 | Updated: 2026-04-30
55
"""
66

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

911

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+
GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
20+
21+
# Okabe-Ito: increase = brand green, decrease = vermillion, flat = adaptive neutral
22+
COLOR_UP = "#009E73"
23+
COLOR_DOWN = "#D55E00"
24+
COLOR_FLAT = INK_MUTED
25+
1026
# Data - Product sales Q1 vs Q4 comparison (10 products showing various patterns)
1127
products = [
1228
"Laptop Pro",
@@ -21,39 +37,36 @@
2137
"Monitor Stand",
2238
]
2339

24-
# Sales figures in thousands ($K)
2540
sales_q1 = [245, 180, 120, 195, 85, 110, 45, 30, 75, 55]
2641
sales_q4 = [310, 220, 195, 160, 145, 130, 95, 85, 70, 40]
2742

28-
# Color coding by change direction
2943
colors = []
3044
for q1, q4 in zip(sales_q1, sales_q4, strict=True):
3145
if q4 > q1:
32-
colors.append("#306998") # Python Blue for increase
46+
colors.append(COLOR_UP)
3347
elif q4 < q1:
34-
colors.append("#FFD43B") # Python Yellow for decrease
48+
colors.append(COLOR_DOWN)
3549
else:
36-
colors.append("#888888") # Gray for no change
50+
colors.append(COLOR_FLAT)
3751

38-
# Create figure
52+
# Plot
3953
fig = go.Figure()
4054

41-
# Add slope lines for each product
4255
for i, product in enumerate(products):
4356
fig.add_trace(
4457
go.Scatter(
4558
x=[0, 1],
4659
y=[sales_q1[i], sales_q4[i]],
4760
mode="lines+markers",
4861
line={"color": colors[i], "width": 3},
49-
marker={"size": 14},
62+
marker={"size": 14, "color": colors[i]},
5063
name=product,
5164
showlegend=False,
5265
hovertemplate=f"{product}<br>Q1: ${sales_q1[i]}K<br>Q4: ${sales_q4[i]}K<extra></extra>",
5366
)
5467
)
5568

56-
# Add labels at start points (Q1)
69+
# Labels at Q1 (left side)
5770
for i, product in enumerate(products):
5871
fig.add_annotation(
5972
x=-0.05,
@@ -64,7 +77,7 @@
6477
font={"size": 16, "color": colors[i]},
6578
)
6679

67-
# Add labels at end points (Q4)
80+
# Labels at Q4 (right side)
6881
for i, product in enumerate(products):
6982
fig.add_annotation(
7083
x=1.05,
@@ -75,35 +88,39 @@
7588
font={"size": 16, "color": colors[i]},
7689
)
7790

78-
# Layout
91+
# Style
7992
fig.update_layout(
93+
paper_bgcolor=PAGE_BG,
94+
plot_bgcolor=PAGE_BG,
95+
font={"color": INK},
8096
title={
81-
"text": "Product Sales Q1 vs Q4 · slope-basic · plotly · pyplots.ai",
82-
"font": {"size": 28},
97+
"text": "Product Sales Q1 vs Q4 · slope-basic · plotly · anyplot.ai",
98+
"font": {"size": 28, "color": INK},
8399
"x": 0.5,
84100
"xanchor": "center",
85101
},
86102
xaxis={
87103
"tickmode": "array",
88104
"tickvals": [0, 1],
89105
"ticktext": ["Q1 2024", "Q4 2024"],
90-
"tickfont": {"size": 22},
91-
"range": [-0.4, 1.4],
106+
"tickfont": {"size": 22, "color": INK_SOFT},
107+
"range": [-0.5, 1.5],
92108
"showgrid": False,
93109
"zeroline": False,
110+
"linecolor": INK_SOFT,
94111
},
95112
yaxis={
96-
"title": {"text": "Sales ($K)", "font": {"size": 22}},
97-
"tickfont": {"size": 18},
113+
"title": {"text": "Sales ($K)", "font": {"size": 22, "color": INK}},
114+
"tickfont": {"size": 18, "color": INK_SOFT},
98115
"showgrid": True,
99116
"gridwidth": 1,
100-
"gridcolor": "rgba(0,0,0,0.1)",
117+
"gridcolor": GRID,
101118
"zeroline": False,
119+
"linecolor": INK_SOFT,
102120
},
103-
template="plotly_white",
104-
margin={"l": 200, "r": 200, "t": 80, "b": 60},
121+
margin={"l": 220, "r": 220, "t": 80, "b": 60},
105122
)
106123

107-
# Save outputs
108-
fig.write_image("plot.png", width=1600, height=900, scale=3)
109-
fig.write_html("plot.html")
124+
# Save
125+
fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3)
126+
fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn")

0 commit comments

Comments
 (0)