Skip to content

Commit 547cc9b

Browse files
feat(bokeh): implement area-basic
Add basic area chart implementation for bokeh library using varea glyph. Includes semi-transparent fill, line overlay, and proper grid styling.
1 parent 2ce46bd commit 547cc9b

2 files changed

Lines changed: 185 additions & 31 deletions

File tree

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""
2+
area-basic: Basic Area Chart
3+
Implementation for: bokeh
4+
Variant: default
5+
Python: 3.10+
6+
"""
7+
8+
from typing import TYPE_CHECKING, Optional
9+
10+
import pandas as pd
11+
from bokeh.models import ColumnDataSource
12+
from bokeh.plotting import figure
13+
14+
15+
if TYPE_CHECKING:
16+
from bokeh.plotting import Figure
17+
18+
19+
def create_plot(
20+
data: pd.DataFrame,
21+
x: str,
22+
y: str,
23+
fill_alpha: float = 0.5,
24+
line_color: Optional[str] = None,
25+
title: Optional[str] = None,
26+
x_label: Optional[str] = None,
27+
y_label: Optional[str] = None,
28+
width: int = 1600,
29+
height: int = 900,
30+
**kwargs,
31+
) -> "Figure":
32+
"""
33+
Create a basic filled area chart using bokeh.
34+
35+
A simple filled area chart showing a single data series over time or
36+
sequential x-values. The area between the data line and the baseline
37+
(zero) is filled with a semi-transparent color.
38+
39+
Args:
40+
data: Input DataFrame with x and y columns
41+
x: Column name for x-axis values
42+
y: Column name for y-axis values
43+
fill_alpha: Transparency of the filled area (default: 0.5)
44+
line_color: Color of the line and fill (default: bokeh blue)
45+
title: Chart title (optional)
46+
x_label: Label for x-axis (optional, defaults to column name)
47+
y_label: Label for y-axis (optional, defaults to column name)
48+
width: Figure width in pixels (default: 1600)
49+
height: Figure height in pixels (default: 900)
50+
**kwargs: Additional parameters passed to figure
51+
52+
Returns:
53+
Bokeh Figure object
54+
55+
Raises:
56+
ValueError: If data is empty or fill_alpha is out of range
57+
KeyError: If required columns not found
58+
59+
Example:
60+
>>> data = pd.DataFrame({
61+
... 'Month': [1, 2, 3, 4, 5, 6],
62+
... 'Sales': [100, 120, 90, 140, 160, 130]
63+
... })
64+
>>> fig = create_plot(data, x='Month', y='Sales', title='Monthly Sales')
65+
"""
66+
# Input validation
67+
if data.empty:
68+
raise ValueError("Data cannot be empty")
69+
70+
for col in [x, y]:
71+
if col not in data.columns:
72+
available = ", ".join(data.columns)
73+
raise KeyError(f"Column '{col}' not found. Available columns: {available}")
74+
75+
if not 0 <= fill_alpha <= 1:
76+
raise ValueError(f"fill_alpha must be between 0 and 1, got {fill_alpha}")
77+
78+
# Set default color (bokeh blue)
79+
color = line_color or "#1f77b4"
80+
81+
# Sort data by x to ensure proper area rendering
82+
plot_data = data[[x, y]].dropna().sort_values(by=x).reset_index(drop=True)
83+
84+
# Create ColumnDataSource
85+
source = ColumnDataSource(data={"x": plot_data[x], "y": plot_data[y], "y0": [0] * len(plot_data)})
86+
87+
# Create figure
88+
p = figure(
89+
width=width,
90+
height=height,
91+
title=title or "Area Chart",
92+
x_axis_label=x_label or x,
93+
y_axis_label=y_label or y,
94+
toolbar_location="above",
95+
tools="pan,wheel_zoom,box_zoom,reset,save",
96+
**kwargs,
97+
)
98+
99+
# Draw the filled area from baseline (0) to y values
100+
p.varea(x="x", y1="y0", y2="y", source=source, fill_color=color, fill_alpha=fill_alpha)
101+
102+
# Draw line on top for better visibility
103+
p.line(x="x", y="y", source=source, line_color=color, line_width=2)
104+
105+
# Styling
106+
p.title.text_font_size = "14pt"
107+
p.title.align = "center"
108+
109+
# Grid styling - subtle
110+
p.xgrid.grid_line_alpha = 0.3
111+
p.ygrid.grid_line_alpha = 0.3
112+
p.xgrid.grid_line_dash = [6, 4]
113+
p.ygrid.grid_line_dash = [6, 4]
114+
115+
# Axis styling
116+
p.xaxis.axis_label_text_font_size = "12pt"
117+
p.yaxis.axis_label_text_font_size = "12pt"
118+
p.xaxis.major_label_text_font_size = "10pt"
119+
p.yaxis.major_label_text_font_size = "10pt"
120+
121+
return p
122+
123+
124+
if __name__ == "__main__":
125+
import numpy as np
126+
127+
# Sample data: Monthly website traffic over a year
128+
np.random.seed(42)
129+
months = list(range(1, 13))
130+
base_traffic = [1000, 1100, 1050, 1200, 1400, 1600, 1500, 1550, 1700, 1650, 1800, 2000]
131+
noise = np.random.normal(0, 50, 12)
132+
traffic = [max(0, int(b + n)) for b, n in zip(base_traffic, noise, strict=False)]
133+
134+
data = pd.DataFrame({"Month": months, "Visitors": traffic})
135+
136+
# Create plot
137+
fig = create_plot(
138+
data,
139+
x="Month",
140+
y="Visitors",
141+
title="Monthly Website Traffic",
142+
x_label="Month",
143+
y_label="Visitors (thousands)",
144+
fill_alpha=0.5,
145+
)
146+
147+
# Save as PNG using webdriver-manager for automatic chromedriver
148+
from bokeh.io import export_png
149+
from selenium import webdriver
150+
from selenium.webdriver.chrome.options import Options
151+
from selenium.webdriver.chrome.service import Service
152+
from webdriver_manager.chrome import ChromeDriverManager
153+
154+
chrome_options = Options()
155+
chrome_options.add_argument("--headless")
156+
chrome_options.add_argument("--no-sandbox")
157+
chrome_options.add_argument("--disable-dev-shm-usage")
158+
159+
service = Service(ChromeDriverManager().install())
160+
driver = webdriver.Chrome(service=service, options=chrome_options)
161+
162+
export_png(fig, filename="plot.png", webdriver=driver)
163+
driver.quit()
164+
print("Plot saved to plot.png")

specs/area-basic.md

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,46 @@
11
# area-basic: Basic Area Chart
22

3-
<!--
4-
Spec Template Version: 1.0.0
5-
Created: 2025-12-01
6-
Last Updated: 2025-12-01
7-
-->
8-
93
**Spec Version:** 1.0.0
104

115
## Description
126

13-
Create a simple area chart that displays a single filled area beneath a line, ideal for showing how a quantity changes over time or another continuous variable. The filled area emphasizes the magnitude of values and cumulative totals.
7+
A simple filled area chart showing a single data series over time or sequential x-values. The area between the data line and the baseline (typically zero) is filled with a semi-transparent color to emphasize the magnitude of values.
148

159
## Data Requirements
1610

17-
- **x**: Numeric or datetime column for the x-axis (continuous variable, typically time or sequence)
18-
- **y**: Numeric column for the y-axis (the values to plot)
11+
- **x**: Sequential or time-series values for the x-axis (numeric or datetime)
12+
- **y**: Numeric values to plot on the y-axis
1913

2014
## Optional Parameters
2115

22-
- `color`: Fill color for the area (type: string, default: "steelblue")
23-
- `alpha`: Fill transparency level (type: float 0.0-1.0, default: 0.6)
24-
- `line_color`: Color of the top line (type: string, default: same as color)
25-
- `line_width`: Width of the top line (type: float, default: 1.5)
26-
- `title`: Plot title (type: string, default: None)
27-
- `xlabel`: Custom x-axis label (type: string, default: column name)
28-
- `ylabel`: Custom y-axis label (type: string, default: column name)
29-
- `figsize`: Figure size (type: tuple, default: (16, 9))
16+
- `fill_alpha`: Transparency of the filled area (type: float, default: 0.5)
17+
- `line_color`: Color of the line and fill (type: str, default: library default)
18+
- `title`: Chart title (type: str, default: None)
19+
- `x_label`: Label for x-axis (type: str, default: column name)
20+
- `y_label`: Label for y-axis (type: str, default: column name)
3021

3122
## Quality Criteria
3223

33-
- [ ] X and Y axes are labeled with column names (or custom labels if provided)
34-
- [ ] Grid is visible but subtle with alpha=0.3
35-
- [ ] Area fill is clearly visible with appropriate transparency
36-
- [ ] Line on top of area provides clear boundary
24+
- [ ] X and Y axes are labeled with meaningful names
25+
- [ ] Grid is visible but subtle (alpha <= 0.5)
26+
- [ ] Area fill is semi-transparent (alpha between 0.3 and 0.7)
27+
- [ ] Line on top of fill area is visible
3728
- [ ] No overlapping axis labels or tick marks
38-
- [ ] Appropriate figure size (16:9 aspect ratio) for readability
39-
- [ ] Title is centered and clearly readable if provided
29+
- [ ] Data accurately represented without distortion
30+
- [ ] Figure has appropriate size (16:9 aspect ratio)
4031

4132
## Expected Output
4233

43-
A clean area chart with a filled region showing values over a continuous axis. The area should be filled with a semi-transparent color, bounded by a line at the top edge. The baseline should be at y=0. Grid lines should help with reading values without overpowering the data. All text elements (labels, title, and tick labels) should be legible at standard display sizes.
34+
A clean area chart with a filled region between the data line and the x-axis baseline. The fill should be semi-transparent to allow grid lines to show through slightly. The line defining the top of the area should be clearly visible. Axes should be properly labeled, and a subtle grid should aid in reading values.
4435

4536
## Tags
4637

47-
trend, time-series, basic, area, continuous, statistical, exploratory
38+
area, trend, time-series, basic, 2d
4839

4940
## Use Cases
5041

51-
- Stock price or market value over time (e.g., portfolio value growth)
52-
- Website traffic visualization (e.g., daily visitors over months)
53-
- Resource usage monitoring (e.g., CPU or memory usage over time)
54-
- Sales trends over time periods (e.g., monthly revenue)
55-
- Temperature or environmental data over time
56-
- Population growth or demographic changes
42+
- Visualizing website traffic over time
43+
- Showing cumulative sales or revenue trends
44+
- Displaying stock price history with emphasis on magnitude
45+
- Monitoring system resource usage over time
46+
- Tracking temperature or weather data trends

0 commit comments

Comments
 (0)