From 271222d5b7f027c51116da25f230465c798e653c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:02 +0000 Subject: [PATCH 1/9] feat(highcharts): implement bar-basic (#312) ## Summary Implements `bar-basic` for **highcharts** library. **Parent Issue:** #202 **Sub-Issue:** #250 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/highcharts/bar/bar-basic/default.py` ## Changes - Rewrites implementation to follow KISS principles (simple sequential script) - Uses 4800x2700 dimensions per style guide - Uses Python Blue (#306998) from color palette - Uses element-specific screenshot for exact dimensions - Removes function-based structure, type hints, and docstrings per plot-generator.md guidelines Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/highcharts/bar/bar-basic/default.py | 261 ++++++++-------------- 1 file changed, 91 insertions(+), 170 deletions(-) diff --git a/plots/highcharts/bar/bar-basic/default.py b/plots/highcharts/bar/bar-basic/default.py index 07247a13fa..2264c2c805 100644 --- a/plots/highcharts/bar/bar-basic/default.py +++ b/plots/highcharts/bar/bar-basic/default.py @@ -1,191 +1,112 @@ """ bar-basic: Basic Bar Chart Library: highcharts - -A fundamental vertical bar chart that visualizes categorical data with numeric values. - -Note: Highcharts requires a license for commercial use. """ -from typing import Optional +import json +import tempfile +import time +import urllib.request +from pathlib import Path import pandas as pd from highcharts_core.chart import Chart from highcharts_core.options import HighchartsOptions from highcharts_core.options.series.bar import ColumnSeries +from selenium import webdriver +from selenium.webdriver.chrome.options import Options + + +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Create chart +chart = Chart(container="container") +chart.options = HighchartsOptions() + +# Chart configuration +chart.options.chart = {"type": "column", "width": 4800, "height": 2700, "backgroundColor": "#ffffff"} + +# Title +chart.options.title = {"text": "Basic Bar Chart", "style": {"fontSize": "48px", "fontWeight": "bold"}} + +# X-axis configuration +chart.options.x_axis = { + "categories": data["category"].tolist(), + "title": {"text": "Product Category", "style": {"fontSize": "40px"}}, + "labels": {"style": {"fontSize": "32px"}}, +} + +# Y-axis configuration +chart.options.y_axis = { + "title": {"text": "Sales Value", "style": {"fontSize": "40px"}}, + "labels": {"style": {"fontSize": "32px"}}, + "min": 0, + "gridLineWidth": 1, + "gridLineDashStyle": "Dot", + "gridLineColor": "rgba(0, 0, 0, 0.15)", +} + +# Create series +series = ColumnSeries() +series.data = data["value"].tolist() +series.name = "Sales Value" +series.color = "#306998" # Python Blue from style guide +chart.add_series(series) -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[int, int] = (10, 6), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: Optional[str] = None, - xlabel: Optional[str] = None, - ylabel: Optional[str] = None, - rotation: int = 0, - width: int = 1600, - height: int = 900, - **kwargs, -) -> Chart: - """ - Create a basic bar chart from DataFrame. - - Args: - data: Input DataFrame with categorical and numeric data - category: Column name for category labels (x-axis) - value: Column name for numeric values (bar heights) - figsize: Figure size as (width, height) in inches (legacy, use width/height instead) - color: Bar fill color - edgecolor: Bar edge color - alpha: Transparency level for bars (0.0 to 1.0) - title: Plot title - xlabel: X-axis label (defaults to column name if None) - ylabel: Y-axis label (defaults to column name if None) - rotation: Rotation angle for x-axis labels - width: Figure width in pixels (default: 1600) - height: Figure height in pixels (default: 900) - **kwargs: Additional parameters passed to chart options - - Returns: - Highcharts Chart object - - Raises: - ValueError: If data is empty - KeyError: If required columns are not found in data - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 30] - ... }) - >>> chart = create_plot(data, 'category', 'value', title='My Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns.tolist()) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Create chart with container ID for rendering - chart = Chart(container="container") - chart.options = HighchartsOptions() - - # Chart configuration - chart.options.chart = {"type": "column", "width": width, "height": height, "backgroundColor": "#ffffff"} - - # Title - if title: - chart.options.title = {"text": title, "style": {"fontSize": "16px", "fontWeight": "bold"}} - else: - chart.options.title = {"text": None} - - # X-axis configuration - categories = data[category].tolist() - x_label = xlabel if xlabel is not None else category - chart.options.x_axis = { - "categories": categories, - "title": {"text": x_label, "style": {"fontSize": "12px"}}, - "labels": {"rotation": -rotation if rotation else 0, "style": {"fontSize": "10px"}}, - } - - # Y-axis configuration with subtle grid (y-axis only per spec) - y_label = ylabel if ylabel is not None else value - chart.options.y_axis = { - "title": {"text": y_label, "style": {"fontSize": "12px"}}, - "min": 0, - "gridLineWidth": 1, - "gridLineDashStyle": "Dot", - "gridLineColor": "rgba(0, 0, 0, 0.15)", - "labels": {"style": {"fontSize": "10px"}}, - } - - # Create series with column type (vertical bars in Highcharts) - series = ColumnSeries() - series.data = data[value].tolist() - series.name = y_label - series.color = color - series.border_color = edgecolor - series.border_width = 1 - - # Set opacity via plot options - chart.options.plot_options = { - "column": {"opacity": alpha, "pointPadding": 0.1, "groupPadding": 0.1, "borderWidth": 1, "colorByPoint": False} - } - - chart.add_series(series) - - # Legend (single series, so hide legend) - chart.options.legend = {"enabled": False} - - # Credits - chart.options.credits = {"enabled": False} - - return chart - - -if __name__ == "__main__": - import tempfile - import time - import urllib.request - from pathlib import Path - - from selenium import webdriver - from selenium.webdriver.chrome.options import Options - - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - chart = create_plot( - sample_data, "category", "value", title="Sales by Product", xlabel="Product Category", ylabel="Sales ($)" - ) - - # Download Highcharts JS (required for headless Chrome which can't load CDN) - 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") - - # Export to PNG via Selenium screenshot - # Note: to_js_literal() includes DOMContentLoaded wrapper and Highcharts.chart() call - html_str = chart.to_js_literal() - html_content = f""" +# Plot options +chart.options.plot_options = { + "column": {"pointPadding": 0.1, "groupPadding": 0.1, "borderWidth": 1, "borderColor": "#000000"} +} + +# Legend (single series, hide) +chart.options.legend = {"enabled": False} + +# Credits +chart.options.credits = {"enabled": False} + +# Export to PNG via Selenium +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") + +opts_json = json.dumps(chart.options.to_dict()) + +html_content = f""" -
- +
+ """ - # 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=1600,900") - - driver = webdriver.Chrome(options=chrome_options) - driver.get(f"file:///{temp_path}") - time.sleep(5) # Wait for chart to render - driver.save_screenshot("plot.png") - driver.quit() - - Path(temp_path).unlink() # Clean up temp file - print("Plot saved to plot.png") +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=5000,3000") + +driver = webdriver.Chrome(options=chrome_options) +driver.get(f"file://{temp_path}") +time.sleep(5) + +# Screenshot the chart element specifically for exact dimensions +container = driver.find_element("id", "container") +container.screenshot("plot.png") +driver.quit() + +Path(temp_path).unlink() From d0bd951a8129b2559fb61e5cb6d80b6f02fdea41 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:12 +0000 Subject: [PATCH 2/9] feat(plotly): implement bar-basic (#300) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **plotly** library. **Parent Issue:** #202 **Sub-Issue:** #221 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/plotly/bar/bar-basic/default.py` ## Changes - Simplified from function-based to KISS style (simple sequential script) - Uses correct color from style guide (#306998 Python Blue) - Outputs correct dimensions (4800 × 2700 px) - Uses `plotly_white` template for clean appearance Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/plotly/bar/bar-basic/default.py | 131 ++++---------------------- 1 file changed, 19 insertions(+), 112 deletions(-) diff --git a/plots/plotly/bar/bar-basic/default.py b/plots/plotly/bar/bar-basic/default.py index 590e8f83b9..41576fde35 100644 --- a/plots/plotly/bar/bar-basic/default.py +++ b/plots/plotly/bar/bar-basic/default.py @@ -3,123 +3,30 @@ Library: plotly """ -from typing import TYPE_CHECKING - import pandas as pd import plotly.graph_objects as go -if TYPE_CHECKING: - pass - - -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[int, int] = (1600, 900), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> go.Figure: - """ - Create a basic vertical bar chart for categorical data comparison. - - A fundamental bar chart that displays rectangular bars with heights - proportional to the values they represent. Each bar corresponds to - a category, making it ideal for comparing quantities across discrete - categories. - - Args: - data: Input DataFrame containing the data to plot. - category: Column name for category labels (x-axis). - value: Column name for numeric values (bar heights). - figsize: Figure size as (width, height) in pixels. Defaults to (1600, 900). - color: Bar fill color. Defaults to "steelblue". - edgecolor: Bar edge/outline color. Defaults to "black". - alpha: Transparency level for bars (0-1). Defaults to 0.8. - title: Plot title. Defaults to None. - xlabel: X-axis label. Defaults to column name if None. - ylabel: Y-axis label. Defaults to column name if None. - rotation: Rotation angle for x-axis labels in degrees. Defaults to 0. - **kwargs: Additional parameters passed to go.Bar. - - Returns: - Plotly Figure object containing the bar chart. - - Raises: - ValueError: If data is empty. - KeyError: If required columns are not found in data. - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C', 'D'], - ... 'value': [45, 78, 52, 91] - ... }) - >>> fig = create_plot(data, 'category', 'value', title='Sales by Product') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Set default labels from column names - x_label = xlabel if xlabel is not None else category - y_label = ylabel if ylabel is not None else value - - # Create figure - fig = go.Figure() - - # Add bar trace - fig.add_trace( - go.Bar( - x=data[category], - y=data[value], - marker={"color": color, "opacity": alpha, "line": {"color": edgecolor, "width": 1}}, - **kwargs, - ) - ) - - # Update layout with styling - fig.update_layout( - title={"text": title, "x": 0.5, "xanchor": "center"} if title else None, - xaxis={"title": {"text": x_label, "font": {"size": 14}}, "tickangle": -rotation, "tickfont": {"size": 12}}, - yaxis={ - "title": {"text": y_label, "font": {"size": 14}}, - "tickfont": {"size": 12}, - "rangemode": "tozero", - "showgrid": True, - "gridwidth": 1, - "gridcolor": "rgba(128, 128, 128, 0.3)", - }, - template="plotly_white", - width=figsize[0], - height=figsize[1], - showlegend=False, - margin={"l": 80, "r": 40, "t": 80 if title else 40, "b": 80}, - ) - - return fig +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) +# Create figure +fig = go.Figure() -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) +fig.add_trace(go.Bar(x=data["category"], y=data["value"], marker_color="#306998")) - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product") +# Layout +fig.update_layout( + title={"text": "Basic Bar Chart", "font": {"size": 20}, "x": 0.5, "xanchor": "center"}, + xaxis_title="Category", + yaxis_title="Value", + template="plotly_white", + font={"size": 16}, + xaxis={"tickfont": {"size": 16}}, + yaxis={"tickfont": {"size": 16}}, +) - # Save - fig.write_image("plot.png", width=1600, height=900, scale=2) - print("Plot saved to plot.png") +# Save as PNG (4800 × 2700 px) +fig.write_image("plot.png", width=1600, height=900, scale=3) From f3b4cdad0b7ce9807fd2d5b63697de081e7db789 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:18 +0000 Subject: [PATCH 3/9] feat(altair): implement bar-basic (#298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **altair** library. **Parent Issue:** #202 **Sub-Issue:** #230 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/altair/bar/bar-basic/default.py` ## Changes - Simplified to KISS style (no functions, classes, or type hints) - Uses Python Blue (#306998) as bar color - Proper dimensions (1600 × 900 with scale_factor=3) - Clear axis labels with appropriate font sizes Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/altair/bar/bar-basic/default.py | 112 ++++---------------------- 1 file changed, 16 insertions(+), 96 deletions(-) diff --git a/plots/altair/bar/bar-basic/default.py b/plots/altair/bar/bar-basic/default.py index 8578abae67..1ece1e12a5 100644 --- a/plots/altair/bar/bar-basic/default.py +++ b/plots/altair/bar/bar-basic/default.py @@ -7,101 +7,21 @@ import pandas as pd -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - *, - color: str = "steelblue", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> alt.Chart: - """ - Create a basic vertical bar chart. - - A fundamental bar chart that visualizes categorical data with numeric values, - ideal for comparing quantities across discrete categories. - - Args: - data: Input DataFrame containing the data to plot. - category: Column name for categorical x-axis values. - value: Column name for numeric y-axis values. - color: Bar fill color. Defaults to "steelblue". - alpha: Transparency level for bars (0-1). Defaults to 0.8. - title: Plot title. Defaults to None. - xlabel: X-axis label. Defaults to column name if None. - ylabel: Y-axis label. Defaults to column name if None. - rotation: Rotation angle for x-axis labels. Defaults to 0. - **kwargs: Additional parameters passed to chart properties. - - Returns: - Altair Chart object. - - Raises: - ValueError: If data is empty. - KeyError: If required columns are not found in data. - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 15] - ... }) - >>> chart = create_plot(data, 'category', 'value', title='Example') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Determine axis labels - x_label = xlabel if xlabel is not None else category - y_label = ylabel if ylabel is not None else value - - # Build x-axis configuration - x_axis = alt.Axis(title=x_label, labelAngle=-rotation if rotation != 0 else 0) - - # Build y-axis configuration with subtle grid - y_axis = alt.Axis(title=y_label, grid=True, gridOpacity=0.3) - - # Create the bar chart - chart = ( - alt.Chart(data) - .mark_bar(color=color, opacity=alpha) - .encode( - x=alt.X(f"{category}:N", axis=x_axis, sort=None), - y=alt.Y(f"{value}:Q", axis=y_axis, scale=alt.Scale(domain=[0, data[value].max() * 1.1])), - tooltip=[alt.Tooltip(f"{category}:N", title=x_label), alt.Tooltip(f"{value}:Q", title=y_label)], - ) - .properties(width=800, height=450) - ) - - # Add title if provided - if title is not None: - chart = chart.properties(title=title) - - # Configure chart appearance - chart = chart.configure_axis(labelFontSize=12, titleFontSize=14).configure_title(fontSize=16, anchor="middle") - - return chart - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Create chart +chart = ( + alt.Chart(data) + .mark_bar(color="#306998") + .encode( + x=alt.X("category:N", title="Category", axis=alt.Axis(labelFontSize=16, titleFontSize=20)), + y=alt.Y("value:Q", title="Value", axis=alt.Axis(labelFontSize=16, titleFontSize=20)), ) + .properties(width=1600, height=900, title=alt.Title(text="Basic Bar Chart", fontSize=20)) +) - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product") - - # Save - fig.save("plot.png", scale_factor=2.0) - print("Plot saved to plot.png") +# Save as PNG (1600 × 900 with scale_factor=3 = 4800 × 2700) +chart.save("plot.png", scale_factor=3.0) From d2faeb71e19f3b4ed67640400da11b1b5d39c0fc Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:39 +0000 Subject: [PATCH 4/9] feat(matplotlib): implement bar-basic (#288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **matplotlib** library. **Parent Issue:** #202 **Sub-Issue:** #213 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/matplotlib/bar/bar-basic/default.py` ## Details - Simple vertical bar chart following KISS style guide - Uses Python Blue (#306998) color from style guide - Properly sized for 4800 × 2700 px output (figsize=(16, 9) with dpi=300) - Includes meaningful axis labels, title, and subtle y-axis grid Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/matplotlib/bar/bar-basic/default.py | 119 ++++------------------ 1 file changed, 17 insertions(+), 102 deletions(-) diff --git a/plots/matplotlib/bar/bar-basic/default.py b/plots/matplotlib/bar/bar-basic/default.py index c031b8ba2e..bb080eb16e 100644 --- a/plots/matplotlib/bar/bar-basic/default.py +++ b/plots/matplotlib/bar/bar-basic/default.py @@ -5,110 +5,25 @@ import matplotlib.pyplot as plt import pandas as pd -from matplotlib.figure import Figure -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[float, float] = (10, 6), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> Figure: - """ - Create a basic vertical bar chart from a DataFrame. +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) - A fundamental bar chart that visualizes categorical data with numeric values, - ideal for comparing quantities across discrete categories. +# Create plot +fig, ax = plt.subplots(figsize=(16, 9)) +ax.bar(data["category"], data["value"], color="#306998", edgecolor="white", linewidth=1) - Args: - data: Input DataFrame containing the data to plot. - category: Column name for category labels (x-axis). - value: Column name for numeric values (bar heights). - figsize: Figure size as (width, height) in inches. - color: Bar fill color. - edgecolor: Bar edge color. - alpha: Transparency level for bars (0.0 to 1.0). - title: Optional plot title. - xlabel: X-axis label. Defaults to category column name if None. - ylabel: Y-axis label. Defaults to value column name if None. - rotation: Rotation angle for x-axis labels in degrees. - **kwargs: Additional keyword arguments passed to ax.bar(). +# Labels and styling +ax.set_xlabel("Category", fontsize=20) +ax.set_ylabel("Value", fontsize=20) +ax.set_title("Basic Bar Chart", fontsize=20) +ax.tick_params(axis="both", labelsize=16) +ax.grid(axis="y", alpha=0.3) +ax.set_axisbelow(True) +ax.set_ylim(bottom=0) - Returns: - Matplotlib Figure object containing the bar chart. - - Raises: - ValueError: If data is empty. - KeyError: If required columns are not found in the DataFrame. - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 15] - ... }) - >>> fig = create_plot(data, 'category', 'value', title='Sample Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Create figure - fig, ax = plt.subplots(figsize=figsize) - - # Extract data - categories = data[category] - values = data[value] - - # Plot bars - ax.bar(categories, values, color=color, edgecolor=edgecolor, alpha=alpha, **kwargs) - - # Set axis labels - ax.set_xlabel(xlabel if xlabel is not None else category) - ax.set_ylabel(ylabel if ylabel is not None else value) - - # Set title if provided - if title is not None: - ax.set_title(title) - - # Add subtle grid on y-axis only - ax.yaxis.grid(True, alpha=0.3) - ax.set_axisbelow(True) - - # Rotate x-axis labels if specified - if rotation != 0: - plt.xticks(rotation=rotation, ha="right" if rotation > 0 else "left") - - # Ensure y-axis starts at zero - ax.set_ylim(bottom=0) - - # Adjust layout - plt.tight_layout() - - return fig - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product", xlabel="Product", ylabel="Sales ($)") - - # Save - plt.savefig("plot.png", dpi=300, bbox_inches="tight") - print("Plot saved to plot.png") +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From 264d428519bc8e3547ade4b72f298f98dc7e8fbb Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:11 +0000 Subject: [PATCH 5/9] feat(seaborn): implement bar-basic (#293) ## Summary Implements `bar-basic` for **seaborn** library. **Parent Issue:** #202 **Sub-Issue:** #216 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/seaborn/barplot/bar-basic/default.py` ## Changes - Simplified implementation following KISS style from plot-generator.md - Sequential script without functions, type hints, or docstrings - Uses seaborn `barplot` with `hue` parameter for seaborn 0.14+ API compatibility - Follows default-style-guide.md color palette (#306998, #FFD43B, #DC2626, #059669, #8B5CF6) - 16:9 aspect ratio figure (16, 9) for proper output dimensions - Y-axis grid for visual clarity Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/seaborn/barplot/bar-basic/default.py | 133 +++++---------------- 1 file changed, 27 insertions(+), 106 deletions(-) diff --git a/plots/seaborn/barplot/bar-basic/default.py b/plots/seaborn/barplot/bar-basic/default.py index 5bb9eae7c5..fb129d2712 100644 --- a/plots/seaborn/barplot/bar-basic/default.py +++ b/plots/seaborn/barplot/bar-basic/default.py @@ -3,114 +3,35 @@ Library: seaborn """ -from typing import TYPE_CHECKING - import matplotlib.pyplot as plt import pandas as pd import seaborn as sns -if TYPE_CHECKING: - from matplotlib.figure import Figure - - -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[float, float] = (10, 6), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> "Figure": - """ - Create a basic vertical bar chart for categorical data comparison. - - A fundamental bar chart displaying rectangular bars with heights proportional - to their numeric values, ideal for comparing quantities across categories. - - Args: - data: Input DataFrame containing the data to plot - category: Column name for category labels (x-axis) - value: Column name for numeric values (bar heights) - figsize: Figure size as (width, height) in inches - color: Bar fill color - edgecolor: Bar edge color - alpha: Transparency level for bars (0-1) - title: Plot title (optional) - xlabel: X-axis label (defaults to column name if None) - ylabel: Y-axis label (defaults to column name if None) - rotation: Rotation angle for x-axis labels in degrees - **kwargs: Additional parameters passed to seaborn.barplot - - Returns: - Matplotlib Figure object - - Raises: - ValueError: If data is empty - KeyError: If required columns not found in data - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 15] - ... }) - >>> fig = create_plot(data, 'category', 'value', title='Sample Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Create figure - fig, ax = plt.subplots(figsize=figsize) - - # Plot data using seaborn barplot - sns.barplot(data=data, x=category, y=value, color=color, edgecolor=edgecolor, alpha=alpha, ax=ax, **kwargs) - - # Set y-axis to start at zero for accurate visual comparison - ax.set_ylim(bottom=0) - - # Add subtle grid on y-axis only - ax.yaxis.grid(True, alpha=0.3) - ax.set_axisbelow(True) - - # Labels - ax.set_xlabel(xlabel if xlabel is not None else category) - ax.set_ylabel(ylabel if ylabel is not None else value) - - # Title - if title is not None: - ax.set_title(title) - - # Rotate x-axis labels if specified - if rotation != 0: - plt.xticks(rotation=rotation, ha="right") - - # Layout - plt.tight_layout() - - return fig - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product", xlabel="Product", ylabel="Sales ($)") - - # Save - ALWAYS use 'plot.png'! - plt.savefig("plot.png", dpi=300, bbox_inches="tight") - print("Plot saved to plot.png") +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Create plot +fig, ax = plt.subplots(figsize=(16, 9)) +sns.barplot( + data=data, + x="category", + y="value", + hue="category", + palette=["#306998", "#FFD43B", "#DC2626", "#059669", "#8B5CF6"], + legend=False, + ax=ax, +) + +# Labels and styling +ax.set_xlabel("Category", fontsize=20) +ax.set_ylabel("Value", fontsize=20) +ax.set_title("Basic Bar Chart", fontsize=20) +ax.tick_params(axis="both", labelsize=16) +ax.yaxis.grid(True, alpha=0.3) +ax.set_axisbelow(True) + +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From 1f41a99b807f2040224ed7afb744ddf675e4909b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:12 +0000 Subject: [PATCH 6/9] feat(pygal): implement bar-basic (#283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **pygal** library. **Parent Issue:** #202 **Sub-Issue:** #244 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/pygal/bar/bar-basic/default.py` ## Changes - Rewrote implementation following KISS style guide - Simple sequential script: imports → data → plot → save - Uses pyplots color palette (#306998 Python Blue) - 4800×2700px output with properly scaled fonts - Clean white background with y-guides - No functions, no classes, no if __name__ block Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/pygal/bar/bar-basic/default.py | 144 +++++++-------------------- 1 file changed, 36 insertions(+), 108 deletions(-) diff --git a/plots/pygal/bar/bar-basic/default.py b/plots/pygal/bar/bar-basic/default.py index fe5464a4a5..49f56290d0 100644 --- a/plots/pygal/bar/bar-basic/default.py +++ b/plots/pygal/bar/bar-basic/default.py @@ -3,115 +3,43 @@ Library: pygal """ -import pandas as pd import pygal from pygal.style import Style -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[int, int] = (1600, 900), - color: str = "#3498db", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> pygal.Bar: - """ - Create a basic vertical bar chart for categorical data comparison. - - Args: - data: Input DataFrame containing the data to plot. - category: Column name for category labels (x-axis). - value: Column name for numeric values (bar heights). - figsize: Figure size as (width, height) in pixels. - color: Bar fill color. - alpha: Transparency level for bars (0.0 to 1.0). - title: Optional plot title. - xlabel: X-axis label (defaults to category column name). - ylabel: Y-axis label (defaults to value column name). - rotation: Rotation angle for x-axis labels. - **kwargs: Additional parameters passed to pygal.Bar. - - Returns: - pygal.Bar chart object. - - Raises: - ValueError: If data is empty. - KeyError: If required columns are not found in data. - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 30] - ... }) - >>> chart = create_plot(data, 'category', 'value', title='Sample Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Handle missing values - clean_data = data[[category, value]].dropna() - - # Create custom style with subtle grid and proper colors - custom_style = Style( - background="white", - plot_background="white", - foreground="#333333", - foreground_strong="#333333", - foreground_subtle="#666666", - opacity=str(alpha), - opacity_hover=str(min(alpha + 0.1, 1.0)), - colors=(color,), - guide_stroke_color="#cccccc", - major_guide_stroke_color="#cccccc", - ) - - # Create chart - chart = pygal.Bar( - width=figsize[0], - height=figsize[1], - title=title, - x_title=xlabel if xlabel else category, - y_title=ylabel if ylabel else value, - style=custom_style, - show_legend=False, - show_y_guides=True, - show_x_guides=False, - x_label_rotation=rotation, - print_values=False, - range=(0, None), - **kwargs, - ) - - # Set x-axis labels - chart.x_labels = [str(cat) for cat in clean_data[category].tolist()] - - # Add data series - chart.add("", clean_data[value].tolist()) - - return chart - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - chart = create_plot(sample_data, "category", "value", title="Sales by Product") - - # Save to PNG - chart.render_to_png("plot.png") - print("Plot saved to plot.png") +# Data +categories = ["Product A", "Product B", "Product C", "Product D", "Product E"] +values = [45, 78, 52, 91, 63] + +# Custom style matching pyplots palette +custom_style = Style( + background="white", + plot_background="white", + foreground="#333333", + foreground_strong="#333333", + foreground_subtle="#666666", + colors=("#306998",), + title_font_size=48, + label_font_size=40, + legend_font_size=40, + value_font_size=32, +) + +# Create chart +chart = pygal.Bar( + width=4800, + height=2700, + title="Basic Bar Chart", + x_title="Category", + y_title="Value", + style=custom_style, + show_legend=False, + show_y_guides=True, +) + +# Add data +chart.x_labels = categories +chart.add("Value", values) + +# Save as PNG +chart.render_to_png("plot.png") From b07580fe205c9d058c4877aef23d8d94d1839beb Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:44 +0000 Subject: [PATCH 7/9] feat(letsplot): implement bar-basic (#302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **letsplot** library. **Parent Issue:** #202 **Sub-Issue:** #257 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/letsplot/bar/bar-basic/default.py` ## Details - Uses `geom_bar(stat='identity')` for bar chart visualization - Follows PyPlots default style guide (4800 × 2700 px output at scale=3) - Uses Python Blue (#306998) as primary color - Includes theme_minimal() with customized font sizes for readability Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/letsplot/bar/bar-basic/default.py | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 plots/letsplot/bar/bar-basic/default.py diff --git a/plots/letsplot/bar/bar-basic/default.py b/plots/letsplot/bar/bar-basic/default.py new file mode 100644 index 0000000000..dd43f0cbfe --- /dev/null +++ b/plots/letsplot/bar/bar-basic/default.py @@ -0,0 +1,28 @@ +""" +bar-basic: Basic Bar Chart +Library: letsplot +""" + +import pandas as pd +from lets_plot import LetsPlot, aes, element_text, geom_bar, ggplot, ggsave, ggsize, labs, theme, theme_minimal + + +LetsPlot.setup_html() + +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Plot +plot = ( + ggplot(data, aes(x="category", y="value")) + + geom_bar(stat="identity", fill="#306998", alpha=0.9) + + labs(x="Category", y="Value", title="Basic Bar Chart") + + theme_minimal() + + theme(plot_title=element_text(size=20), axis_title=element_text(size=20), axis_text=element_text(size=16)) + + ggsize(1600, 900) +) + +# Save (scale 3x to get 4800 × 2700 px) +ggsave(plot, "plot.png", path=".", scale=3) From c64c3897806ace139234819f2fbbdd74f9ef4b0f Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:53 +0000 Subject: [PATCH 8/9] feat(plotnine): implement bar-basic (#291) ## Summary Implements `bar-basic` for **plotnine** library. **Parent Issue:** #202 **Sub-Issue:** #237 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/plotnine/bar/bar-basic/default.py` ## Changes - Simplified implementation following KISS principles (no functions, just sequential code) - Uses Python Blue (#306998) from style guide - Correct figure size (16x9 at 300dpi = 4800x2700px) - Clean axis labels and title - Subtle horizontal grid with no vertical grid lines - Categorical ordering preserved to maintain x-axis order Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/plotnine/bar/bar-basic/default.py | 119 ++++++------------------ 1 file changed, 26 insertions(+), 93 deletions(-) diff --git a/plots/plotnine/bar/bar-basic/default.py b/plots/plotnine/bar/bar-basic/default.py index 206675ae4d..15c60a614a 100644 --- a/plots/plotnine/bar/bar-basic/default.py +++ b/plots/plotnine/bar/bar-basic/default.py @@ -1,102 +1,35 @@ """ bar-basic: Basic Bar Chart Library: plotnine - -A fundamental vertical bar chart that visualizes categorical data with numeric values. """ import pandas as pd from plotnine import aes, geom_bar, ggplot, labs, scale_y_continuous, theme, theme_minimal -from plotnine.ggplot import ggplot as ggplot_type -from plotnine.themes.elements import element_blank, element_line, element_text - - -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[float, float] = (10, 6), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> ggplot_type: - """ - Create a basic vertical bar chart. - - Args: - data: Input DataFrame containing the data to plot - category: Column name for category labels (x-axis) - value: Column name for numeric values (bar heights) - figsize: Figure size as (width, height) - color: Bar fill color - edgecolor: Bar edge color - alpha: Transparency level for bars (0-1) - title: Plot title (optional) - xlabel: X-axis label (defaults to column name if None) - ylabel: Y-axis label (defaults to column name if None) - rotation: Rotation angle for x-axis labels - **kwargs: Additional parameters passed to geom_bar - - Returns: - plotnine ggplot object - - Raises: - ValueError: If data is empty - KeyError: If required columns are not found in data - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C'], - ... 'value': [10, 20, 15] - ... }) - >>> fig = create_plot(data, 'category', 'value', title='Sample Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Set default labels to column names if not provided - x_label = xlabel if xlabel is not None else category - y_label = ylabel if ylabel is not None else value - - # Create the plot - plot = ( - ggplot(data, aes(x=category, y=value)) - + geom_bar(stat="identity", fill=color, color=edgecolor, alpha=alpha, **kwargs) - + labs(x=x_label, y=y_label, title=title) - + scale_y_continuous(expand=(0, 0, 0.05, 0)) # Start y-axis at zero - + theme_minimal() - + theme( - figure_size=figsize, - axis_text_x=element_text(rotation=rotation, ha="right" if rotation else "center"), - panel_grid_major_x=element_blank(), # Remove vertical grid lines - panel_grid_minor=element_blank(), # Remove minor grid lines - panel_grid_major_y=element_line(alpha=0.3), # Subtle horizontal grid - ) +from plotnine.themes.elements import element_blank, element_line + + +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Preserve category order +data["category"] = pd.Categorical(data["category"], categories=data["category"], ordered=True) + +# Plot +plot = ( + ggplot(data, aes(x="category", y="value")) + + geom_bar(stat="identity", fill="#306998", width=0.7) + + labs(x="Category", y="Value", title="Basic Bar Chart") + + scale_y_continuous(expand=(0, 0, 0.05, 0)) + + theme_minimal(base_size=16) + + theme( + figure_size=(16, 9), + panel_grid_major_x=element_blank(), + panel_grid_minor=element_blank(), + panel_grid_major_y=element_line(alpha=0.3), ) +) - return plot - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product") - - # Save - fig.save("plot.png", dpi=300) - print("Plot saved to plot.png") +# Save +plot.save("plot.png", dpi=300) From 6ceb033fc00d18fadb3279f18f736e7cd809b32c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 20:26:58 +0000 Subject: [PATCH 9/9] feat(bokeh): implement bar-basic (#305) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `bar-basic` for **bokeh** library. **Parent Issue:** #202 **Sub-Issue:** #225 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/bokeh/vbar/bar-basic/default.py` ## Changes - Simplified to KISS-style sequential script (no functions/classes) - 4800×2700px output with proper typography sizing (20pt labels, 16pt ticks) - Uses ColumnDataSource and vbar glyph method per library guidelines - Python Blue (#306998) color from style guide - Subtle grid styling with y-axis grid only Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> --- plots/bokeh/vbar/bar-basic/default.py | 174 +++++--------------------- 1 file changed, 33 insertions(+), 141 deletions(-) diff --git a/plots/bokeh/vbar/bar-basic/default.py b/plots/bokeh/vbar/bar-basic/default.py index 6ddc86e890..949329a97a 100644 --- a/plots/bokeh/vbar/bar-basic/default.py +++ b/plots/bokeh/vbar/bar-basic/default.py @@ -3,150 +3,42 @@ Library: bokeh """ -from typing import TYPE_CHECKING - 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 as Figure - - -def create_plot( - data: pd.DataFrame, - category: str, - value: str, - figsize: tuple[int, int] = (1600, 900), - color: str = "steelblue", - edgecolor: str = "black", - alpha: float = 0.8, - title: str | None = None, - xlabel: str | None = None, - ylabel: str | None = None, - rotation: int = 0, - **kwargs, -) -> "Figure": - """ - Create a basic vertical bar chart. - - A fundamental bar chart that visualizes categorical data with numeric values, - ideal for comparing quantities across discrete categories. - - Args: - data: Input DataFrame with categorical and numeric columns - category: Column name for category labels (x-axis) - value: Column name for numeric values (bar heights) - figsize: Figure size as (width, height) in pixels. Defaults to (1600, 900). - color: Bar fill color. Defaults to "steelblue". - edgecolor: Bar edge color. Defaults to "black". - alpha: Transparency level for bars (0-1). Defaults to 0.8. - title: Plot title. Defaults to None. - xlabel: X-axis label. Defaults to category column name. - ylabel: Y-axis label. Defaults to value column name. - rotation: Rotation angle for x-axis labels in degrees. Defaults to 0. - **kwargs: Additional parameters passed to figure. - - Returns: - Bokeh figure object with the bar chart. - - Raises: - ValueError: If data is empty. - KeyError: If required columns are not found in data. - - Example: - >>> data = pd.DataFrame({ - ... 'category': ['A', 'B', 'C', 'D'], - ... 'value': [10, 25, 15, 30] - ... }) - >>> fig = create_plot(data, 'category', 'value', title='Sample Bar Chart') - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - for col in [category, value]: - if col not in data.columns: - available = ", ".join(data.columns.tolist()) - raise KeyError(f"Column '{col}' not found. Available: {available}") - - # Prepare data - drop NaN values - plot_data = data[[category, value]].dropna() - - # Get categories as list for x_range - categories = plot_data[category].astype(str).tolist() - - # Create ColumnDataSource - source = ColumnDataSource(data={"categories": categories, "values": plot_data[value].tolist()}) - - # Set labels - x_label = xlabel if xlabel is not None else category - y_label = ylabel if ylabel is not None else value - - # Create figure with categorical x-axis - p = figure( - width=figsize[0], - height=figsize[1], - x_range=categories, - title=title, - x_axis_label=x_label, - y_axis_label=y_label, - **kwargs, - ) - - # Calculate bar width (0.8 of available space) - bar_width = 0.8 - - # Add bars - p.vbar( - x="categories", - top="values", - width=bar_width, - source=source, - fill_color=color, - fill_alpha=alpha, - line_color=edgecolor, - line_width=1, - ) - - # Ensure y-axis starts at zero - p.y_range.start = 0 - - # Style grid - subtle y-grid only - p.xgrid.grid_line_color = None - p.ygrid.grid_line_alpha = 0.3 - - # Apply x-axis label rotation if specified - if rotation != 0: - from math import pi - - p.xaxis.major_label_orientation = rotation * pi / 180 - - # Style axis labels - 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" - - # Style title if present - if title: - p.title.text_font_size = "14pt" - p.title.align = "center" - - return p - - -if __name__ == "__main__": - # Sample data for testing - sample_data = pd.DataFrame( - {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} - ) - - # Create plot - fig = create_plot(sample_data, "category", "value", title="Sales by Product", xlabel="Product", ylabel="Sales ($)") - - # Save - export_png(fig, filename="plot.png") - print("Plot saved to plot.png") +# Data +data = pd.DataFrame( + {"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]} +) + +# Create ColumnDataSource +source = ColumnDataSource(data) + +# Create figure with categorical x-axis +p = figure( + width=4800, + height=2700, + x_range=data["category"].tolist(), + title="Basic Bar Chart", + x_axis_label="Category", + y_axis_label="Value", +) + +# Plot vertical bars +p.vbar(x="category", top="value", source=source, width=0.7, color="#306998", alpha=0.8) + +# 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.xgrid.grid_line_color = None +p.ygrid.grid_line_alpha = 0.3 +p.y_range.start = 0 + +# Save +export_png(p, filename="plot.png")