Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions plots/altair/area/area-basic/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
area-basic: Basic Area Chart
Library: altair
"""

import altair as alt
import pandas as pd


# Data
data = pd.DataFrame(
{
"month": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
"sales": [100, 150, 130, 180, 200, 220, 195, 240, 260, 230, 280, 310],
}
)

# Create chart with area and line
chart = (
alt.Chart(data)
.mark_area(opacity=0.5, color="#306998", line={"color": "#306998", "strokeWidth": 2})
.encode(
x=alt.X("month:Q", title="Month", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
y=alt.Y("sales:Q", title="Sales", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
)
.properties(width=1600, height=900, title=alt.TitleParams(text="Basic Area Chart", fontSize=20))
.configure_view(strokeWidth=0)
.configure_axis(grid=True, gridOpacity=0.3)
)

# Save (1600 × 900 × 3 = 4800 × 2700)
chart.save("plot.png", scale_factor=3.0)
Comment on lines +8 to +32
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is missing the required create_plot() function. All plot implementations in this project must follow the standard pattern:

  1. Define a create_plot(data: pd.DataFrame, x: str, y: str, **params) function with:

    • Proper type hints (use TYPE_CHECKING for forward references)
    • Comprehensive docstring with Args, Returns, Raises, and Example sections
    • Input validation (empty data, missing columns, data type checks)
    • Parameter handling with sensible defaults
    • Return the appropriate plot object (altair Chart in this case)
  2. Use if __name__ == "__main__": block for example/test code

The current implementation has hardcoded data in the main body, which prevents the plot from being used programmatically via the API. Please restructure this to match the pattern used in existing implementations like plots/altair/line/line-basic/default.py.

Suggested change
# Data
data = pd.DataFrame(
{
"month": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
"sales": [100, 150, 130, 180, 200, 220, 195, 240, 260, 230, 280, 310],
}
)
# Create chart with area and line
chart = (
alt.Chart(data)
.mark_area(opacity=0.5, color="#306998", line={"color": "#306998", "strokeWidth": 2})
.encode(
x=alt.X("month:Q", title="Month", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
y=alt.Y("sales:Q", title="Sales", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
)
.properties(width=1600, height=900, title=alt.TitleParams(text="Basic Area Chart", fontSize=20))
.configure_view(strokeWidth=0)
.configure_axis(grid=True, gridOpacity=0.3)
)
# Save (1600 × 900 × 3 = 4800 × 2700)
chart.save("plot.png", scale_factor=3.0)
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from altair import Chart
def create_plot(
data: pd.DataFrame,
x: str,
y: str,
*,
width: int = 1600,
height: int = 900,
area_color: str = "#306998",
opacity: float = 0.5,
line_color: str = "#306998",
line_width: int = 2,
x_title: str | None = None,
y_title: str | None = None,
title: str = "Basic Area Chart",
grid: bool = True,
grid_opacity: float = 0.3,
**params: Any,
) -> "alt.Chart":
"""
Create a basic area chart using Altair.
Args:
data (pd.DataFrame): Input data.
x (str): Column name for x-axis (must be numeric or datetime).
y (str): Column name for y-axis (must be numeric).
width (int, optional): Chart width in pixels. Defaults to 1600.
height (int, optional): Chart height in pixels. Defaults to 900.
area_color (str, optional): Area fill color. Defaults to "#306998".
opacity (float, optional): Area opacity. Defaults to 0.5.
line_color (str, optional): Line color. Defaults to "#306998".
line_width (int, optional): Line width. Defaults to 2.
x_title (str, optional): X-axis title. Defaults to column name.
y_title (str, optional): Y-axis title. Defaults to column name.
title (str, optional): Chart title. Defaults to "Basic Area Chart".
grid (bool, optional): Show grid. Defaults to True.
grid_opacity (float, optional): Grid opacity. Defaults to 0.3.
**params: Additional keyword arguments for extensibility.
Returns:
alt.Chart: Altair area chart object.
Raises:
ValueError: If data is empty, or x/y columns are missing or of wrong type.
Example:
>>> import pandas as pd
>>> from plots.altair.area.area-basic.default import create_plot
>>> df = pd.DataFrame({'month': [1,2,3], 'sales': [100, 150, 130]})
>>> chart = create_plot(df, x='month', y='sales')
>>> chart.show()
"""
if data.empty:
raise ValueError("Input data is empty.")
if x not in data.columns:
raise ValueError(f"Column '{x}' not found in data.")
if y not in data.columns:
raise ValueError(f"Column '{y}' not found in data.")
# Check types
if not pd.api.types.is_numeric_dtype(data[x]) and not pd.api.types.is_datetime64_any_dtype(data[x]):
raise ValueError(f"Column '{x}' must be numeric or datetime.")
if not pd.api.types.is_numeric_dtype(data[y]):
raise ValueError(f"Column '{y}' must be numeric.")
x_axis_title = x_title if x_title is not None else x.capitalize()
y_axis_title = y_title if y_title is not None else y.capitalize()
chart = (
alt.Chart(data)
.mark_area(opacity=opacity, color=area_color, line={"color": line_color, "strokeWidth": line_width})
.encode(
x=alt.X(f"{x}:Q", title=x_axis_title, axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
y=alt.Y(f"{y}:Q", title=y_axis_title, axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
)
.properties(width=width, height=height, title=alt.TitleParams(text=title, fontSize=20))
.configure_view(strokeWidth=0)
.configure_axis(grid=grid, gridOpacity=grid_opacity)
)
return chart
if __name__ == "__main__":
# Example usage
data = pd.DataFrame(
{
"month": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
"sales": [100, 150, 130, 180, 200, 220, 195, 240, 260, 230, 280, 310],
}
)
chart = create_plot(data, x="month", y="sales")
# Save (1600 × 900 × 3 = 4800 × 2700)
chart.save("plot.png", scale_factor=3.0)

Copilot uses AI. Check for mistakes.
201 changes: 46 additions & 155 deletions plots/bokeh/varea/area-basic/default.py
Original file line number Diff line number Diff line change
@@ -1,164 +1,55 @@
"""
area-basic: Basic Area Chart
Implementation for: bokeh
Variant: default
Python: 3.10+
Library: bokeh
"""

from typing import TYPE_CHECKING, Optional

import pandas as pd
from bokeh.io import export_png
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure


if TYPE_CHECKING:
from bokeh.plotting import Figure


def create_plot(
data: pd.DataFrame,
x: str,
y: str,
fill_alpha: float = 0.5,
line_color: Optional[str] = None,
title: Optional[str] = None,
x_label: Optional[str] = None,
y_label: Optional[str] = None,
width: int = 1600,
height: int = 900,
**kwargs,
) -> "Figure":
"""
Create a basic filled area chart using bokeh.

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
(zero) is filled with a semi-transparent color.

Args:
data: Input DataFrame with x and y columns
x: Column name for x-axis values
y: Column name for y-axis values
fill_alpha: Transparency of the filled area (default: 0.5)
line_color: Color of the line and fill (default: bokeh blue)
title: Chart title (optional)
x_label: Label for x-axis (optional, defaults to column name)
y_label: Label for y-axis (optional, defaults to column name)
width: Figure width in pixels (default: 1600)
height: Figure height in pixels (default: 900)
**kwargs: Additional parameters passed to figure

Returns:
Bokeh Figure object

Raises:
ValueError: If data is empty or fill_alpha is out of range
KeyError: If required columns not found

Example:
>>> data = pd.DataFrame({
... 'Month': [1, 2, 3, 4, 5, 6],
... 'Sales': [100, 120, 90, 140, 160, 130]
... })
>>> fig = create_plot(data, x='Month', y='Sales', title='Monthly Sales')
"""
# Input validation
if data.empty:
raise ValueError("Data cannot be empty")

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}")

if not 0 <= fill_alpha <= 1:
raise ValueError(f"fill_alpha must be between 0 and 1, got {fill_alpha}")

# Set default color (bokeh blue)
color = line_color or "#1f77b4"

# Sort data by x to ensure proper area rendering
plot_data = data[[x, y]].dropna().sort_values(by=x).reset_index(drop=True)

# Create ColumnDataSource
source = ColumnDataSource(data={"x": plot_data[x], "y": plot_data[y], "y0": [0] * len(plot_data)})

# Create figure
p = figure(
width=width,
height=height,
title=title or "Area Chart",
x_axis_label=x_label or x,
y_axis_label=y_label or y,
toolbar_location="above",
tools="pan,wheel_zoom,box_zoom,reset,save",
**kwargs,
)

# Draw the filled area from baseline (0) to y values
p.varea(x="x", y1="y0", y2="y", source=source, fill_color=color, fill_alpha=fill_alpha)

# Draw line on top for better visibility
p.line(x="x", y="y", source=source, line_color=color, line_width=2)

# Styling
p.title.text_font_size = "14pt"
p.title.align = "center"

# Grid styling - subtle
p.xgrid.grid_line_alpha = 0.3
p.ygrid.grid_line_alpha = 0.3
p.xgrid.grid_line_dash = [6, 4]
p.ygrid.grid_line_dash = [6, 4]

# Axis styling
p.xaxis.axis_label_text_font_size = "12pt"
p.yaxis.axis_label_text_font_size = "12pt"
p.xaxis.major_label_text_font_size = "10pt"
p.yaxis.major_label_text_font_size = "10pt"

return p


if __name__ == "__main__":
import numpy as np

# Sample data: Monthly website traffic over a year
np.random.seed(42)
months = list(range(1, 13))
base_traffic = [1000, 1100, 1050, 1200, 1400, 1600, 1500, 1550, 1700, 1650, 1800, 2000]
noise = np.random.normal(0, 50, 12)
traffic = [max(0, int(b + n)) for b, n in zip(base_traffic, noise, strict=False)]

data = pd.DataFrame({"Month": months, "Visitors": traffic})

# Create plot
fig = create_plot(
data,
x="Month",
y="Visitors",
title="Monthly Website Traffic",
x_label="Month",
y_label="Visitors (thousands)",
fill_alpha=0.5,
)

# Save as PNG using webdriver-manager for automatic chromedriver
from bokeh.io import export_png
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")

service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)

export_png(fig, filename="plot.png", webdriver=driver)
driver.quit()
print("Plot saved to plot.png")
# Data
data = pd.DataFrame(
{
"month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"sales": [120, 135, 148, 162, 175, 195, 210, 198, 185, 170, 158, 190],
}
)

# Create x positions for categorical months
x = list(range(len(data["month"])))
y = data["sales"].tolist()

source = ColumnDataSource(data={"x": x, "y": y, "month": data["month"]})

# Create figure
p = figure(
width=4800,
height=2700,
title="Monthly Sales Volume",
x_axis_label="Month",
y_axis_label="Sales ($)",
x_range=(-0.5, len(x) - 0.5),
)

# Plot area (varea fills from y1 to y2)
p.varea(x="x", y1=0, y2="y", source=source, fill_alpha=0.7, fill_color="#306998")

# Add line on top for clearer boundary
p.line(x="x", y="y", source=source, line_width=2, line_color="#306998")

# Configure x-axis ticks to show month labels
p.xaxis.ticker = x
p.xaxis.major_label_overrides = dict(enumerate(data["month"]))

# Styling
p.title.text_font_size = "20pt"
p.xaxis.axis_label_text_font_size = "20pt"
p.yaxis.axis_label_text_font_size = "20pt"
p.xaxis.major_label_text_font_size = "16pt"
p.yaxis.major_label_text_font_size = "16pt"
p.grid.grid_line_alpha = 0.3

# Save
export_png(p, filename="plot.png")
Comment on lines 1 to +55
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is missing the required create_plot() function. All plot implementations in this project must follow the standard pattern:

  1. Define a create_plot(data: pd.DataFrame, x: str, y: str, **params) function with:

    • Proper type hints (use TYPE_CHECKING for forward references)
    • Comprehensive docstring with Args, Returns, Raises, and Example sections
    • Input validation (empty data, missing columns, data type checks)
    • Parameter handling with sensible defaults
    • Return the appropriate plot object (bokeh Figure in this case)
  2. Use if __name__ == "__main__": block for example/test code

The current implementation has hardcoded data in the main body, which prevents the plot from being used programmatically via the API. Please restructure this to match the pattern used in existing implementations like plots/bokeh/line/line-basic/default.py.

Copilot uses AI. Check for mistakes.
109 changes: 109 additions & 0 deletions plots/highcharts/area/area-basic/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""
area-basic: Basic Area Chart
Library: highcharts
"""

import tempfile
import time
import urllib.request
from pathlib import Path

from highcharts_core.chart import Chart
from highcharts_core.options import HighchartsOptions
from highcharts_core.options.series.area import AreaSeries
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


# Data - Monthly sales example
sales = [100, 150, 130, 180, 200, 220, 195, 240, 280, 310, 290, 350]

# Create chart
chart = Chart(container="container")
chart.options = HighchartsOptions()

# Chart configuration
chart.options.chart = {
"type": "area",
"width": 4800,
"height": 2700,
"backgroundColor": "#ffffff",
"style": {"fontFamily": "Arial, sans-serif"},
}

# Title
chart.options.title = {"text": "Monthly Sales Trend", "style": {"fontSize": "48px"}}

# Axes
chart.options.x_axis = {
"title": {"text": "Month", "style": {"fontSize": "40px"}},
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"labels": {"style": {"fontSize": "32px"}, "enabled": True},
"gridLineWidth": 1,
"gridLineColor": "rgba(0, 0, 0, 0.1)",
"tickmarkPlacement": "on",
}

chart.options.y_axis = {
"title": {"text": "Sales ($)", "style": {"fontSize": "40px"}},
"labels": {"style": {"fontSize": "32px"}},
"gridLineWidth": 1,
"gridLineColor": "rgba(0, 0, 0, 0.1)",
}

# Legend
chart.options.legend = {"enabled": False}

# Create area series
series = AreaSeries()
series.data = sales
series.name = "Sales"
series.color = "#306998"
series.fill_opacity = 0.5
series.line_width = 4
series.marker = {"enabled": True, "radius": 6, "fillColor": "#306998", "lineWidth": 2, "lineColor": "#ffffff"}

chart.add_series(series)

# Download Highcharts JS
highcharts_url = "https://code.highcharts.com/highcharts.js"
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
highcharts_js = response.read().decode("utf-8")

# Generate HTML with inline scripts
html_str = chart.to_js_literal()
html_content = f"""<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>{highcharts_js}</script>
</head>
<body style="margin:0;">
<div id="container" style="width: 4800px; height: 2700px;"></div>
<script>{html_str}</script>
</body>
</html>"""

# Write temp HTML and take screenshot
with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f:
f.write(html_content)
temp_path = f.name

chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=4800,2800")

driver = webdriver.Chrome(options=chrome_options)
driver.set_window_size(4800, 2800)
driver.get(f"file://{temp_path}")
time.sleep(5)

# Get the container element and screenshot it directly
container = driver.find_element("id", "container")
container.screenshot("plot.png")
driver.quit()

Path(temp_path).unlink()
Comment on lines +1 to +109
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is missing the required create_plot() function. All plot implementations in this project must follow the standard pattern:

  1. Define a create_plot(data: pd.DataFrame, x: str, y: str, **params) function with:

    • Proper type hints (use TYPE_CHECKING for forward references)
    • Comprehensive docstring with Args, Returns, Raises, and Example sections
    • Input validation (empty data, missing columns, data type checks)
    • Parameter handling with sensible defaults
    • Return the appropriate plot object (highcharts Chart in this case)
  2. Use if __name__ == "__main__": block for example/test code

The current implementation has hardcoded data in the main body, which prevents the plot from being used programmatically via the API. Please restructure this to match the pattern used in existing implementations like plots/highcharts/line/line-basic/default.py.

Copilot uses AI. Check for mistakes.
44 changes: 44 additions & 0 deletions plots/letsplot/area/area-basic/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
area-basic: Basic Area Chart
Library: letsplot
"""

import pandas as pd
from lets_plot import (
LetsPlot,
aes,
element_text,
geom_area,
geom_line,
ggplot,
ggsave,
ggsize,
labs,
scale_x_continuous,
theme,
theme_minimal,
)


LetsPlot.setup_html()

# Data
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
data = pd.DataFrame(
{"month_num": range(len(months)), "sales": [120, 135, 148, 162, 175, 195, 210, 198, 185, 170, 158, 190]}
)

# Plot
plot = (
ggplot(data, aes(x="month_num", y="sales"))
+ geom_area(fill="#306998", alpha=0.5)
+ geom_line(color="#306998", size=2)
+ scale_x_continuous(breaks=list(range(len(months))), labels=months)
+ labs(x="Month", y="Sales", title="Basic Area Chart")
+ theme_minimal()
+ theme(axis_title=element_text(size=20), axis_text=element_text(size=16), plot_title=element_text(size=20))
+ ggsize(1600, 900)
)

# Save - scale 3x to get 4800 × 2700 px
ggsave(plot, "plot.png", path=".", scale=3)
Comment on lines +1 to +44
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is missing the required create_plot() function. All plot implementations in this project must follow the standard pattern:

  1. Define a create_plot(data: pd.DataFrame, x: str, y: str, **params) function with:

    • Proper type hints (use TYPE_CHECKING for forward references)
    • Comprehensive docstring with Args, Returns, Raises, and Example sections
    • Input validation (empty data, missing columns, data type checks)
    • Parameter handling with sensible defaults
    • Return the appropriate plot object (lets-plot ggplot in this case)
  2. Use if __name__ == "__main__": block for example/test code

The current implementation has hardcoded data in the main body, which prevents the plot from being used programmatically via the API. Please restructure this to match the pattern used in existing implementations like plots/letsplot/line/line-basic/default.py.

Copilot uses AI. Check for mistakes.
Loading
Loading