diff --git a/plots/plotnine/area/area-basic/default.py b/plots/plotnine/area/area-basic/default.py new file mode 100644 index 0000000000..a725d50c15 --- /dev/null +++ b/plots/plotnine/area/area-basic/default.py @@ -0,0 +1,141 @@ +""" +area-basic: Basic Area Chart +Implementation for: plotnine +Variant: default +Python: 3.10+ +""" + +from typing import TYPE_CHECKING, Optional + +import numpy as np +import pandas as pd +from plotnine import aes, element_line, element_text, geom_area, geom_line, ggplot, labs, theme, theme_minimal + + +if TYPE_CHECKING: + from plotnine import ggplot as GGPlot + + +def create_plot( + data: pd.DataFrame, + x: str, + y: str, + title: Optional[str] = None, + xlabel: Optional[str] = None, + ylabel: Optional[str] = None, + color: str = "steelblue", + alpha: float = 0.6, + line_color: Optional[str] = None, + line_width: float = 1.5, + width: int = 16, + height: int = 9, + **kwargs, +) -> "GGPlot": + """ + Create a basic area chart showing values over a continuous axis using plotnine (ggplot2 syntax). + + Args: + data: Input DataFrame with required columns + x: Column name for x-axis values (numeric or datetime) + y: Column name for y-axis values (numeric) + title: Plot title (optional) + xlabel: Custom x-axis label (optional, defaults to x column name) + ylabel: Custom y-axis label (optional, defaults to y column name) + color: Fill color for the area (default: 'steelblue') + alpha: Fill transparency level (default: 0.6) + line_color: Color of the top line (default: same as color) + line_width: Width of the top line (default: 1.5) + width: Figure width in inches (default: 16) + height: Figure height in inches (default: 9) + **kwargs: Additional parameters for geom_area + + Returns: + plotnine ggplot object + + Raises: + ValueError: If data is empty + KeyError: If required columns not found + + Example: + >>> data = pd.DataFrame({ + ... 'time': [1, 2, 3, 4, 5], + ... 'value': [10, 25, 15, 30, 20] + ... }) + >>> plot = create_plot(data, x='time', y='value') + """ + # Input validation + if data.empty: + raise ValueError("Data cannot be empty") + + # Check required columns + for col in [x, y]: + if col not in data.columns: + available = ", ".join(data.columns) + raise KeyError(f"Column '{col}' not found. Available columns: {available}") + + # Use the same color for line if not specified + if line_color is None: + line_color = color + + # Sort data by x to ensure proper area rendering + data_sorted = data.sort_values(by=x).copy() + + # Create the ggplot object with area and line + plot = ( + ggplot(data_sorted, aes(x=x, y=y)) + + geom_area(fill=color, alpha=alpha, **kwargs) + + geom_line(color=line_color, size=line_width) + + labs(title=title or "Area Chart", x=xlabel or x, y=ylabel or y) + + theme_minimal() + + theme( + figure_size=(width, height), + plot_title=element_text(size=14, weight="bold", ha="center"), + axis_title=element_text(size=11), + axis_text=element_text(size=10), + panel_grid_major=element_line(alpha=0.3, linetype="dashed"), + panel_grid_minor=element_line(alpha=0), + ) + ) + + return plot + + +if __name__ == "__main__": + # Sample data for testing - simulating time series data + np.random.seed(42) # For reproducibility + + # Generate sample time series data (e.g., monthly website visitors) + months = pd.date_range(start="2024-01-01", periods=12, freq="MS") + + # Create realistic-looking growth pattern with some variation + base_values = np.linspace(1000, 2500, 12) + noise = np.random.normal(0, 150, 12) + values = base_values + noise + + # Ensure no negative values + values = np.maximum(values, 100) + + data = pd.DataFrame( + { + "Month": range(1, 13), # Use numeric for simpler plotting + "Visitors": values, + } + ) + + # Create plot + plot = create_plot( + data, + x="Month", + y="Visitors", + title="Monthly Website Visitors (2024)", + xlabel="Month", + ylabel="Number of Visitors", + color="#3498db", + alpha=0.5, + line_color="#2980b9", + line_width=2, + ) + + # Save for inspection + plot.save("plot.png", dpi=300, verbose=False) + print("Plot saved to plot.png") diff --git a/specs/area-basic.md b/specs/area-basic.md index 8df6bb9902..4c0ac798d3 100644 --- a/specs/area-basic.md +++ b/specs/area-basic.md @@ -10,20 +10,19 @@ Last Updated: 2025-12-01 ## Description -Create a simple filled area chart showing a single data series over time or sequential x-values. -Perfect for visualizing cumulative values, trends with emphasis on magnitude, and comparing values to a baseline. -Works with any dataset containing sequential x-values and numeric y-values. +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. ## Data Requirements -- **x**: Sequential values for x-axis (datetime, numeric, or categorical) -- **y**: Numeric values representing the area height at each x point +- **x**: Numeric or datetime column for the x-axis (continuous variable, typically time or sequence) +- **y**: Numeric column for the y-axis (the values to plot) ## Optional Parameters - `color`: Fill color for the area (type: string, default: "steelblue") -- `alpha`: Transparency level for fill (type: float 0.0-1.0, default: 0.4) -- `line_alpha`: Transparency level for edge line (type: float 0.0-1.0, default: 1.0) +- `alpha`: Fill transparency level (type: float 0.0-1.0, default: 0.6) +- `line_color`: Color of the top line (type: string, default: same as color) +- `line_width`: Width of the top line (type: float, default: 1.5) - `title`: Plot title (type: string, default: None) - `xlabel`: Custom x-axis label (type: string, default: column name) - `ylabel`: Custom y-axis label (type: string, default: column name) @@ -33,30 +32,25 @@ Works with any dataset containing sequential x-values and numeric y-values. - [ ] X and Y axes are labeled with column names (or custom labels if provided) - [ ] Grid is visible but subtle with alpha=0.3 -- [ ] Area fill is clearly visible with appropriate transparency (alpha ~0.4) -- [ ] Edge line is visible to define the data boundary +- [ ] Area fill is clearly visible with appropriate transparency +- [ ] Line on top of area provides clear boundary - [ ] No overlapping axis labels or tick marks -- [ ] Colorblind-safe colors used -- [ ] Appropriate figure size (16x9 aspect ratio) for readability +- [ ] Appropriate figure size (16:9 aspect ratio) for readability - [ ] Title is centered and clearly readable if provided ## Expected Output -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 while still emphasizing magnitude. -A solid edge line should clearly define the top boundary of the data. -The plot should be immediately understandable without additional explanation. -All text elements should be legible at standard display sizes. +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. ## Tags -area, trend, time-series, basic, magnitude, cumulative, exploratory +trend, time-series, basic, area, continuous, statistical, exploratory ## Use Cases -- Visualizing cumulative values over time (e.g., total revenue growth) -- Showing trends with emphasis on magnitude (e.g., stock prices) -- Comparing values to a baseline (e.g., temperature above/below average) -- Website traffic visualization over time -- Resource utilization monitoring (CPU, memory usage) -- Population or growth trends +- Stock price or market value over time (e.g., portfolio value growth) +- Website traffic visualization (e.g., daily visitors over months) +- Resource usage monitoring (e.g., CPU or memory usage over time) +- Sales trends over time periods (e.g., monthly revenue) +- Temperature or environmental data over time +- Population growth or demographic changes