Skip to content

Commit 0ca1dc9

Browse files
feat(plotly): implement area-basic
Implement basic area chart for plotly library following KISS style guidelines. Uses go.Scatter with fill='tozeroy' to create filled area under line. - Uses Python Blue (#306998) from style guide - Proper axis labels and title - 4800x2700px output (1600x900 @ scale 3)
1 parent 27357ca commit 0ca1dc9

1 file changed

Lines changed: 37 additions & 167 deletions

File tree

Lines changed: 37 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,46 @@
11
"""
22
area-basic: Basic Area Chart
3-
Implementation for: plotly
4-
Variant: default
5-
Python: 3.10+
3+
Library: plotly
64
"""
75

8-
from typing import TYPE_CHECKING, Optional
9-
106
import pandas as pd
117
import plotly.graph_objects as go
128

139

14-
if TYPE_CHECKING:
15-
pass
16-
17-
18-
def create_plot(
19-
data: pd.DataFrame,
20-
x: str,
21-
y: str,
22-
title: Optional[str] = None,
23-
xlabel: Optional[str] = None,
24-
ylabel: Optional[str] = None,
25-
color: str = "rgba(99, 110, 250, 0.5)",
26-
line_color: Optional[str] = None,
27-
line_width: float = 2.0,
28-
fill_to: str = "tozeroy",
29-
height: int = 900,
30-
width: int = 1600,
31-
**kwargs,
32-
) -> go.Figure:
33-
"""
34-
Create a basic area chart showing quantitative data over a continuous interval.
35-
36-
The area between the line and the x-axis is filled with color, emphasizing
37-
the magnitude of values. Ideal for showing trends and cumulative totals.
38-
39-
Args:
40-
data: Input DataFrame with required columns
41-
x: Column name for x-axis values (typically time or sequential data)
42-
y: Column name for y-axis values (numeric)
43-
title: Plot title (optional)
44-
xlabel: Custom x-axis label (optional, defaults to column name)
45-
ylabel: Custom y-axis label (optional, defaults to column name)
46-
color: Fill color for the area with alpha (default: semi-transparent blue)
47-
line_color: Color of the line at top of area (default: derived from fill color)
48-
line_width: Width of the line (default: 2.0)
49-
fill_to: Fill mode - 'tozeroy', 'tonexty', 'none' (default: 'tozeroy')
50-
height: Figure height in pixels (default: 900)
51-
width: Figure width in pixels (default: 1600)
52-
**kwargs: Additional parameters passed to plotly Scatter trace
53-
54-
Returns:
55-
Plotly Figure object
56-
57-
Raises:
58-
ValueError: If data is empty
59-
KeyError: If required columns not found
60-
61-
Example:
62-
>>> data = pd.DataFrame({
63-
... 'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
64-
... 'Sales': [100, 150, 130, 180, 200]
65-
... })
66-
>>> fig = create_plot(data, x='Month', y='Sales', title='Monthly Sales')
67-
"""
68-
# Input validation
69-
if data.empty:
70-
raise ValueError("Data cannot be empty")
71-
72-
# Check required columns
73-
for col in [x, y]:
74-
if col not in data.columns:
75-
available = ", ".join(data.columns)
76-
raise KeyError(f"Column '{col}' not found. Available columns: {available}")
77-
78-
# Derive line color from fill color if not provided
79-
if line_color is None:
80-
# Use a solid version of the fill color (darker)
81-
line_color = "rgb(99, 110, 250)"
82-
83-
# Create the figure
84-
fig = go.Figure()
85-
86-
# Add the area trace
87-
fig.add_trace(
88-
go.Scatter(
89-
x=data[x],
90-
y=data[y],
91-
mode="lines",
92-
fill=fill_to,
93-
fillcolor=color,
94-
line={"color": line_color, "width": line_width},
95-
name=y,
96-
hovertemplate=f"<b>{x}</b>: %{{x}}<br><b>{y}</b>: %{{y:,.2f}}<extra></extra>",
97-
**kwargs,
98-
)
10+
# Data
11+
data = pd.DataFrame(
12+
{
13+
"month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
14+
"sales": [120, 135, 148, 162, 175, 195, 210, 198, 185, 170, 158, 190],
15+
}
16+
)
17+
18+
# Create figure
19+
fig = go.Figure()
20+
21+
fig.add_trace(
22+
go.Scatter(
23+
x=data["month"],
24+
y=data["sales"],
25+
mode="lines",
26+
fill="tozeroy",
27+
fillcolor="rgba(48, 105, 152, 0.4)",
28+
line={"color": "#306998", "width": 2},
29+
name="Sales",
9930
)
100-
101-
# Update layout for professional appearance
102-
fig.update_layout(
103-
title={
104-
"text": title or "Area Chart",
105-
"font": {"size": 18, "family": "Arial, sans-serif"},
106-
"x": 0.5,
107-
"xanchor": "center",
108-
},
109-
xaxis={
110-
"title": {"text": xlabel or x, "font": {"size": 14}},
111-
"showgrid": True,
112-
"gridcolor": "rgba(128, 128, 128, 0.3)",
113-
"gridwidth": 1,
114-
"zeroline": False,
115-
"showline": True,
116-
"linewidth": 1,
117-
"linecolor": "rgba(128, 128, 128, 0.5)",
118-
},
119-
yaxis={
120-
"title": {"text": ylabel or y, "font": {"size": 14}},
121-
"showgrid": True,
122-
"gridcolor": "rgba(128, 128, 128, 0.3)",
123-
"gridwidth": 1,
124-
"zeroline": True,
125-
"zerolinewidth": 1,
126-
"zerolinecolor": "rgba(128, 128, 128, 0.5)",
127-
"showline": True,
128-
"linewidth": 1,
129-
"linecolor": "rgba(128, 128, 128, 0.5)",
130-
},
131-
plot_bgcolor="white",
132-
paper_bgcolor="white",
133-
height=height,
134-
width=width,
135-
showlegend=False,
136-
hovermode="x unified",
137-
hoverlabel={"bgcolor": "white", "font_size": 12, "font_family": "Arial, sans-serif"},
138-
margin={"l": 80, "r": 40, "t": 80, "b": 60},
139-
)
140-
141-
return fig
142-
143-
144-
if __name__ == "__main__":
145-
import numpy as np
146-
147-
# Sample data: Monthly website traffic over a year
148-
np.random.seed(42)
149-
150-
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
151-
152-
# Generate realistic traffic pattern with seasonal variation
153-
base_traffic = 10000
154-
seasonal_factor = [0.8, 0.85, 0.95, 1.0, 1.1, 1.15, 1.2, 1.25, 1.1, 1.0, 0.9, 0.95]
155-
noise = np.random.normal(0, 500, 12)
156-
157-
traffic = [int(base_traffic * sf + n) for sf, n in zip(seasonal_factor, noise, strict=False)]
158-
159-
data = pd.DataFrame({"Month": months, "Visitors": traffic})
160-
161-
# Create the area chart
162-
fig = create_plot(
163-
data,
164-
x="Month",
165-
y="Visitors",
166-
title="Monthly Website Visitors (2024)",
167-
xlabel="Month",
168-
ylabel="Number of Visitors",
169-
color="rgba(99, 110, 250, 0.4)",
170-
line_color="rgb(99, 110, 250)",
171-
line_width=2.5,
172-
)
173-
174-
# Save as PNG
175-
fig.write_image("plot.png", width=1600, height=900, scale=2)
176-
print("Plot saved to plot.png")
31+
)
32+
33+
# Layout
34+
fig.update_layout(
35+
title={"text": "Monthly Sales", "font": {"size": 20}, "x": 0.5, "xanchor": "center"},
36+
xaxis_title={"text": "Month", "font": {"size": 20}},
37+
yaxis_title={"text": "Sales", "font": {"size": 20}},
38+
template="plotly_white",
39+
xaxis={"tickfont": {"size": 16}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"},
40+
yaxis={"tickfont": {"size": 16}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"},
41+
showlegend=False,
42+
margin={"l": 80, "r": 40, "t": 80, "b": 80},
43+
)
44+
45+
# Save
46+
fig.write_image("plot.png", width=1600, height=900, scale=3)

0 commit comments

Comments
 (0)