Skip to content

Commit cd8a8f3

Browse files
Merge branch 'main' into implementation/step-basic/letsplot
2 parents 3f0e66d + 1045771 commit cd8a8f3

14 files changed

Lines changed: 1525 additions & 937 deletions

File tree

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
step-basic: Basic Step Plot
3-
Library: altair 6.0.0 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: altair 6.1.0 | Python 3.13.13
4+
Quality: 87/100 | Updated: 2026-04-30
55
"""
66

7-
# Workaround for altair.py file shadowing the altair module
87
import os
98
import sys
109

1110

11+
# Workaround: this file is named altair.py, which shadows the altair module
1212
_cwd = os.getcwd()
1313
if _cwd in sys.path:
1414
sys.path.remove(_cwd)
@@ -21,40 +21,60 @@
2121

2222
import pandas as pd # noqa: E402, I001
2323

24+
# Theme tokens
25+
THEME = os.getenv("ANYPLOT_THEME", "light")
26+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
27+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
28+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
29+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
30+
BRAND = "#009E73"
2431

25-
# Data - Monthly cumulative sales (shows clear step pattern)
32+
# Data — monthly cumulative software subscription revenue
2633
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
27-
cumulative_sales = [12, 25, 31, 48, 52, 67, 89, 95, 108, 124, 145, 168]
34+
cumulative_revenue = [12, 25, 31, 48, 52, 67, 89, 95, 108, 124, 145, 168]
2835

29-
df = pd.DataFrame({"Month": months, "Cumulative Sales": cumulative_sales})
36+
df = pd.DataFrame({"Month": months, "Cumulative Revenue": cumulative_revenue})
3037

31-
# Create step chart
32-
chart = (
38+
# Step line
39+
line = (
3340
alt.Chart(df)
34-
.mark_line(interpolate="step-after", strokeWidth=4, color="#306998")
41+
.mark_line(interpolate="step-after", strokeWidth=5, color=BRAND)
3542
.encode(
3643
x=alt.X("Month:N", title="Month", sort=months, axis=alt.Axis(labelAngle=0)),
37-
y=alt.Y("Cumulative Sales:Q", title="Cumulative Sales (thousands $)"),
44+
y=alt.Y("Cumulative Revenue:Q", title="Cumulative Revenue (thousands $)"),
3845
)
39-
.properties(width=1600, height=900, title=alt.Title("step-basic · altair · pyplots.ai", fontSize=28))
4046
)
4147

42-
# Add markers at data points to highlight where changes occur
48+
# Markers at each data point
4349
points = (
4450
alt.Chart(df)
45-
.mark_point(size=200, color="#306998", filled=True)
46-
.encode(x=alt.X("Month:N", sort=months), y="Cumulative Sales:Q")
51+
.mark_point(size=220, color=BRAND, filled=True, opacity=1.0)
52+
.encode(x=alt.X("Month:N", sort=months), y="Cumulative Revenue:Q")
4753
)
4854

49-
# Combine line and points
50-
final_chart = (
51-
(chart + points)
52-
.configure_axis(labelFontSize=18, titleFontSize=22, grid=True, gridOpacity=0.3, gridDash=[4, 4])
53-
.configure_view(strokeWidth=0)
55+
# Compose and style
56+
chart = (
57+
(line + points)
58+
.properties(
59+
width=1600,
60+
height=900,
61+
background=PAGE_BG,
62+
title=alt.Title("step-basic · altair · anyplot.ai", fontSize=28, color=INK),
63+
)
64+
.configure_view(fill=PAGE_BG, stroke=INK_SOFT)
65+
.configure_axis(
66+
domainColor=INK_SOFT,
67+
tickColor=INK_SOFT,
68+
gridColor=INK,
69+
gridOpacity=0.10,
70+
labelColor=INK_SOFT,
71+
titleColor=INK,
72+
labelFontSize=18,
73+
titleFontSize=22,
74+
)
75+
.configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK)
5476
)
5577

56-
# Save as PNG (1600 × 900 @ scale 3 = 4800 × 2700)
57-
final_chart.save("plot.png", scale_factor=3.0)
58-
59-
# Save as HTML for interactivity
60-
final_chart.save("plot.html")
78+
# Save
79+
chart.save(f"plot-{THEME}.png", scale_factor=3.0)
80+
chart.save(f"plot-{THEME}.html")
Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,78 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
step-basic: Basic Step Plot
3-
Library: bokeh 3.8.1 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: bokeh 3.9.0 | Python 3.13.13
4+
Quality: 87/100 | Updated: 2026-04-30
55
"""
66

7+
import os
8+
79
from bokeh.io import export_png, output_file
810
from bokeh.models import ColumnDataSource
911
from bokeh.plotting import figure, save
1012

1113

14+
# Theme
15+
THEME = os.getenv("ANYPLOT_THEME", "light")
16+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
17+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
18+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
19+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
20+
BRAND = "#009E73"
21+
1222
# Data - Monthly cumulative sales showing discrete jumps
1323
months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
1424
cumulative_sales = [15, 28, 42, 55, 71, 89, 102, 118, 135, 156, 172, 195]
1525

1626
source = ColumnDataSource(data={"month": months, "sales": cumulative_sales})
1727

18-
# Create figure (4800 × 2700 px)
28+
# Plot
1929
p = figure(
2030
width=4800,
2131
height=2700,
22-
title="step-basic · bokeh · pyplots.ai",
32+
title="step-basic · bokeh · anyplot.ai",
2333
x_axis_label="Month",
2434
y_axis_label="Cumulative Sales (units)",
2535
tools="",
2636
toolbar_location=None,
2737
)
2838

29-
# Step plot using step glyph (post mode - value applies until next change)
30-
p.step(x="month", y="sales", source=source, line_width=4, color="#306998", mode="after")
39+
# Step line (after/post mode - value holds until next change occurs)
40+
p.step(x="month", y="sales", source=source, line_width=5, color=BRAND, mode="after")
3141

32-
# Add markers at data points to show where changes occur
33-
p.scatter(x="month", y="sales", source=source, size=18, color="#FFD43B", line_color="#306998", line_width=3)
42+
# Markers at data points to highlight where changes occur
43+
p.scatter(x="month", y="sales", source=source, size=18, color=BRAND, line_color=PAGE_BG, line_width=3)
3444

35-
# Styling for 4800x2700 px
36-
p.title.text_font_size = "48pt"
37-
p.xaxis.axis_label_text_font_size = "36pt"
38-
p.yaxis.axis_label_text_font_size = "36pt"
39-
p.xaxis.major_label_text_font_size = "28pt"
40-
p.yaxis.major_label_text_font_size = "28pt"
45+
# Style - text sizes for 4800x2700 px canvas
46+
p.title.text_font_size = "28pt"
47+
p.title.text_font_style = "bold"
48+
p.title.text_color = INK
49+
p.xaxis.axis_label_text_font_size = "22pt"
50+
p.yaxis.axis_label_text_font_size = "22pt"
51+
p.xaxis.axis_label_text_color = INK
52+
p.yaxis.axis_label_text_color = INK
53+
p.xaxis.major_label_text_font_size = "18pt"
54+
p.yaxis.major_label_text_font_size = "18pt"
55+
p.xaxis.major_label_text_color = INK_SOFT
56+
p.yaxis.major_label_text_color = INK_SOFT
4157

42-
# Grid styling
43-
p.xgrid.grid_line_alpha = 0.3
44-
p.ygrid.grid_line_alpha = 0.3
45-
p.xgrid.grid_line_dash = "dashed"
46-
p.ygrid.grid_line_dash = "dashed"
58+
# Chrome - axes and ticks
59+
p.xaxis.axis_line_color = INK_SOFT
60+
p.yaxis.axis_line_color = INK_SOFT
61+
p.xaxis.major_tick_line_color = INK_SOFT
62+
p.yaxis.major_tick_line_color = INK_SOFT
4763

48-
# Background
49-
p.background_fill_color = "#fafafa"
64+
# Grid - subtle solid lines
65+
p.xgrid.grid_line_color = INK
66+
p.xgrid.grid_line_alpha = 0.10
67+
p.ygrid.grid_line_color = INK
68+
p.ygrid.grid_line_alpha = 0.10
5069

51-
# Save as PNG
52-
export_png(p, filename="plot.png")
70+
# Background
71+
p.background_fill_color = PAGE_BG
72+
p.border_fill_color = PAGE_BG
73+
p.outline_line_color = INK_SOFT
5374

54-
# Save as HTML for interactivity
55-
output_file("plot.html")
75+
# Save
76+
export_png(p, filename=f"plot-{THEME}.png")
77+
output_file(f"plot-{THEME}.html")
5678
save(p)
Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
step-basic: Basic Step Plot
3-
Library: highcharts unknown | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: highcharts unknown | Python 3.13.13
4+
Quality: 86/100 | Updated: 2026-04-30
55
"""
66

7+
import os
78
import tempfile
89
import time
910
import urllib.request
@@ -16,6 +17,15 @@
1617
from selenium.webdriver.chrome.options import Options
1718

1819

20+
# Theme tokens
21+
THEME = os.getenv("ANYPLOT_THEME", "light")
22+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
23+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
24+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
25+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
26+
GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
27+
BRAND = "#009E73"
28+
1929
# Data - Monthly cumulative sales (thousands of dollars)
2030
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
2131
cumulative_sales = [45, 92, 156, 198, 267, 312, 398, 445, 523, 612, 695, 780]
@@ -29,73 +39,80 @@
2939
"type": "line",
3040
"width": 4800,
3141
"height": 2700,
32-
"backgroundColor": "#ffffff",
42+
"backgroundColor": PAGE_BG,
3343
"marginBottom": 250,
3444
"marginLeft": 200,
3545
}
3646

3747
# Title
3848
chart.options.title = {
39-
"text": "step-basic · highcharts · pyplots.ai",
40-
"style": {"fontSize": "72px", "fontWeight": "bold"},
49+
"text": "step-basic · highcharts · anyplot.ai",
50+
"style": {"fontSize": "72px", "fontWeight": "bold", "color": INK},
4151
}
4252

43-
# X-axis (categories)
53+
# X-axis
4454
chart.options.x_axis = {
4555
"categories": months,
46-
"title": {"text": "Month", "style": {"fontSize": "48px"}},
47-
"labels": {"style": {"fontSize": "36px"}},
56+
"title": {"text": "Month", "style": {"fontSize": "48px", "color": INK}},
57+
"labels": {"style": {"fontSize": "36px", "color": INK_SOFT}},
58+
"lineColor": INK_SOFT,
59+
"tickColor": INK_SOFT,
60+
"gridLineColor": GRID,
4861
}
4962

5063
# Y-axis
5164
chart.options.y_axis = {
52-
"title": {"text": "Cumulative Sales ($K)", "style": {"fontSize": "48px"}},
53-
"labels": {"style": {"fontSize": "36px"}},
65+
"title": {"text": "Cumulative Sales ($K)", "style": {"fontSize": "48px", "color": INK}},
66+
"labels": {"style": {"fontSize": "36px", "color": INK_SOFT}},
5467
"gridLineWidth": 1,
55-
"gridLineColor": "#cccccc",
68+
"gridLineColor": GRID,
5669
}
5770

58-
# Plot options for step line
71+
# Plot options step line with markers
5972
chart.options.plot_options = {
60-
"line": {
61-
"step": "left", # Step style: value applies from this point until next
62-
"lineWidth": 6,
63-
"marker": {"enabled": True, "radius": 12, "symbol": "circle"},
64-
}
73+
"line": {"step": "left", "lineWidth": 6, "marker": {"enabled": True, "radius": 12, "symbol": "circle"}}
6574
}
6675

67-
# Legend
68-
chart.options.legend = {"enabled": True, "itemStyle": {"fontSize": "36px"}}
76+
# Legend disabled — single series
77+
chart.options.legend = {"enabled": False}
6978

70-
# Series data
79+
# Series
7180
series = LineSeries()
7281
series.name = "Cumulative Sales"
7382
series.data = cumulative_sales
74-
series.color = "#306998" # Python Blue
83+
series.color = BRAND
7584

7685
chart.add_series(series)
7786

78-
# Download Highcharts JS for inline embedding
79-
highcharts_url = "https://code.highcharts.com/highcharts.js"
80-
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
81-
highcharts_js = response.read().decode("utf-8")
82-
83-
# Generate HTML with inline script
87+
# Download Highcharts JS for inline embedding (headless Chrome cannot load CDN)
88+
cdn_urls = ["https://cdn.jsdelivr.net/npm/highcharts@11/highcharts.js", "https://code.highcharts.com/highcharts.js"]
89+
highcharts_js = None
90+
for url in cdn_urls:
91+
try:
92+
with urllib.request.urlopen(url, timeout=30) as response:
93+
highcharts_js = response.read().decode("utf-8")
94+
break
95+
except Exception:
96+
continue
97+
if not highcharts_js:
98+
raise RuntimeError("Failed to download Highcharts JS from all CDN sources")
99+
100+
# Build HTML with inline script
84101
html_str = chart.to_js_literal()
85102
html_content = f"""<!DOCTYPE html>
86103
<html>
87104
<head>
88105
<meta charset="utf-8">
89106
<script>{highcharts_js}</script>
90107
</head>
91-
<body style="margin:0;">
108+
<body style="margin:0; background:{PAGE_BG};">
92109
<div id="container" style="width: 4800px; height: 2700px;"></div>
93110
<script>{html_str}</script>
94111
</body>
95112
</html>"""
96113

97-
# Save HTML file
98-
with open("plot.html", "w", encoding="utf-8") as f:
114+
# Save HTML artifact
115+
with open(f"plot-{THEME}.html", "w", encoding="utf-8") as f:
99116
f.write(html_content)
100117

101118
# Screenshot with Selenium
@@ -113,7 +130,7 @@
113130
driver = webdriver.Chrome(options=chrome_options)
114131
driver.get(f"file://{temp_path}")
115132
time.sleep(5)
116-
driver.save_screenshot("plot.png")
133+
driver.save_screenshot(f"plot-{THEME}.png")
117134
driver.quit()
118135

119136
Path(temp_path).unlink()

0 commit comments

Comments
 (0)