From 1c5cd1862aa62917761fd5223d69de85753ece89 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:43 +0000 Subject: [PATCH 01/16] feat(seaborn): implement histogram-basic (#285) ## Summary Implements `histogram-basic` for **seaborn** library. **Parent Issue:** #204 **Sub-Issue:** #217 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/seaborn/histplot/histogram-basic/default.py` ## Changes - Simplified implementation to follow KISS pattern (no functions/classes) - Uses direct script flow as per `prompts/plot-generator.md` - Applied project color palette (#306998 Python Blue) - Set proper font sizes per style guide (20pt labels, 16pt ticks) - Uses seaborn's `histplot` with 30 bins for normal distribution data Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histplot/histogram-basic/default.py | 117 +++--------------- 1 file changed, 16 insertions(+), 101 deletions(-) diff --git a/plots/seaborn/histplot/histogram-basic/default.py b/plots/seaborn/histplot/histogram-basic/default.py index 09bd3f3583..8b665127af 100644 --- a/plots/seaborn/histplot/histogram-basic/default.py +++ b/plots/seaborn/histplot/histogram-basic/default.py @@ -1,113 +1,28 @@ """ histogram-basic: Basic Histogram -Implementation for: seaborn -Variant: default -Python: 3.10+ +Library: seaborn """ -from typing import TYPE_CHECKING, Optional - import matplotlib.pyplot as plt +import numpy as np import pandas as pd import seaborn as sns -if TYPE_CHECKING: - from matplotlib.figure import Figure - - -def create_plot( - data: pd.DataFrame, - column: str, - bins: int = 30, - color: str = "steelblue", - alpha: float = 0.8, - edgecolor: str = "black", - title: Optional[str] = None, - xlabel: Optional[str] = None, - ylabel: Optional[str] = None, - figsize: tuple[float, float] = (16, 9), - **kwargs, -) -> "Figure": - """ - Create a basic histogram showing the distribution of numeric data using seaborn. - - Args: - data: Input DataFrame with required column - column: Column name for numeric values to visualize - bins: Number of bins for histogram (default: 30) - color: Bar color (default: "steelblue") - alpha: Transparency level 0.0-1.0 (default: 0.8) - edgecolor: Border color for bins (default: "black") - title: Plot title (default: None) - xlabel: Custom x-axis label (default: column name) - ylabel: Custom y-axis label (default: "Frequency") - figsize: Figure size as (width, height) (default: (16, 9)) - **kwargs: Additional parameters passed to sns.histplot() - - Returns: - Matplotlib Figure object - - Raises: - ValueError: If data is empty - KeyError: If required column not found - ValueError: If column contains no numeric values - - Example: - >>> data = pd.DataFrame({'Values': [1.5, 2.1, 2.3, 3.2, 3.5, 4.1, 4.5]}) - >>> fig = create_plot(data, column='Values', bins=20) - """ - # Input validation - if data.empty: - raise ValueError("Data cannot be empty") - - # Check required column - if column not in data.columns: - available = ", ".join(data.columns) - raise KeyError(f"Column '{column}' not found. Available: {available}") - - # Check if column has numeric data - if not pd.api.types.is_numeric_dtype(data[column]): - raise ValueError(f"Column '{column}' must contain numeric values") - - # Remove NaN values for histogram - values = data[column].dropna() - - if len(values) == 0: - raise ValueError(f"Column '{column}' contains no valid numeric values") - - # Create figure - fig, ax = plt.subplots(figsize=figsize) - - # Create histogram using seaborn - sns.histplot(data=data, x=column, bins=bins, color=color, alpha=alpha, edgecolor=edgecolor, ax=ax, **kwargs) - - # Apply styling - ax.set_xlabel(xlabel or column) - ax.set_ylabel(ylabel or "Frequency") - ax.grid(True, axis="y", alpha=0.3, linestyle="--") - - # Title - if title: - ax.set_title(title, fontsize=14, fontweight="bold") - - # Tight layout to avoid label clipping - plt.tight_layout() - - return fig - - -if __name__ == "__main__": - # Sample data for testing - import numpy as np +# Data +np.random.seed(42) +data = pd.DataFrame({"value": np.random.normal(100, 15, 500)}) - np.random.seed(42) - data = pd.DataFrame({"Values": np.random.normal(loc=100, scale=15, size=1000)}) +# Create plot +fig, ax = plt.subplots(figsize=(16, 9)) +sns.histplot(data=data, x="value", bins=30, color="#306998", alpha=0.8, edgecolor="white", ax=ax) - # Create plot - fig = create_plot(data, column="Values", bins=40, title="Distribution of Values") +# Labels and styling +ax.set_xlabel("Value", fontsize=20) +ax.set_ylabel("Frequency", fontsize=20) +ax.set_title("Basic Histogram", fontsize=20) +ax.tick_params(axis="both", labelsize=16) +ax.grid(True, alpha=0.3, axis="y") - # Save for inspection - plt.savefig("plot.png", dpi=300, bbox_inches="tight") - print("Plot saved to plot.png") - plt.show() +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From ff6261d35582490bb13673c962dcce749b3e3c8a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:32:46 +0000 Subject: [PATCH 02/16] feat(matplotlib): implement histogram-basic (#281) ## Summary Implements `histogram-basic` for **matplotlib** library. **Parent Issue:** #204 **Sub-Issue:** #212 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/matplotlib/hist/histogram-basic/default.py` ## Details - Uses `ax.hist()` with 30 bins for smooth distribution visualization - Follows default style guide: 16:9 aspect ratio (figsize 16x9), Python Blue (#306998) - White edge on bars for visual separation - Proper font sizes: title/axis labels 20pt, tick labels 16pt - Y-axis grid for easier frequency reading Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../hist/histogram-basic/default.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 plots/matplotlib/hist/histogram-basic/default.py diff --git a/plots/matplotlib/hist/histogram-basic/default.py b/plots/matplotlib/hist/histogram-basic/default.py new file mode 100644 index 0000000000..7c59f56e73 --- /dev/null +++ b/plots/matplotlib/hist/histogram-basic/default.py @@ -0,0 +1,26 @@ +""" +histogram-basic: Basic Histogram +Library: matplotlib +""" + +import matplotlib.pyplot as plt +import numpy as np + + +# Data +np.random.seed(42) +values = np.random.normal(100, 15, 500) + +# Create plot +fig, ax = plt.subplots(figsize=(16, 9)) +ax.hist(values, bins=30, alpha=0.8, color="#306998", edgecolor="white", linewidth=0.5) + +# Labels and styling +ax.set_xlabel("Value", fontsize=20) +ax.set_ylabel("Frequency", fontsize=20) +ax.set_title("Basic Histogram", fontsize=20) +ax.tick_params(axis="both", labelsize=16) +ax.grid(True, alpha=0.3, axis="y") + +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From 97d7448861406874fa842e694b65c81dd4d6c267 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:05 +0000 Subject: [PATCH 03/16] feat(altair): implement histogram-basic (#289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `histogram-basic` for **altair** library. **Parent Issue:** #204 **Sub-Issue:** #236 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/altair/bar/histogram-basic/default.py` ## Details - Uses `mark_bar()` with binning for histogram visualization - Follows the Python Blue color (#306998) from the style guide - Outputs at 4800×2700 px (1600×900 with scale_factor=3.0) - Proper axis labels and title Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/altair/bar/histogram-basic/default.py | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 plots/altair/bar/histogram-basic/default.py diff --git a/plots/altair/bar/histogram-basic/default.py b/plots/altair/bar/histogram-basic/default.py new file mode 100644 index 0000000000..a98f8eb813 --- /dev/null +++ b/plots/altair/bar/histogram-basic/default.py @@ -0,0 +1,26 @@ +""" +histogram-basic: Basic Histogram +Library: altair +""" + +import altair as alt +import numpy as np +import pandas as pd + + +# Data +np.random.seed(42) +data = pd.DataFrame({"value": np.random.normal(100, 15, 500)}) + +# Create histogram chart +chart = ( + alt.Chart(data) + .mark_bar(color="#306998", opacity=0.8) + .encode(alt.X("value:Q", bin=alt.Bin(maxbins=30), title="Value"), alt.Y("count()", title="Frequency")) + .properties(width=1600, height=900, title="Basic Histogram") + .configure_axis(labelFontSize=16, titleFontSize=20) + .configure_title(fontSize=20) +) + +# Save as PNG (1600 × 900 at scale 3 = 4800 × 2700) +chart.save("plot.png", scale_factor=3.0) From 524deb4a7b28b61f2ecb42b9bec3d642f85640f6 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:15 +0000 Subject: [PATCH 04/16] feat(letsplot): implement histogram-basic (#303) ## Summary Implements `histogram-basic` for **letsplot** library. **Parent Issue:** #204 **Sub-Issue:** #264 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/letsplot/histogram/histogram-basic/default.py` ## Details - Uses lets-plot's `geom_histogram()` with 30 bins - Follows Python Blue color palette (#306998) from style guide - Output: 4800 x 2700 px PNG (1600x900 base with scale=3) - Clean KISS-style implementation without functions/classes Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histogram/histogram-basic/default.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 plots/letsplot/histogram/histogram-basic/default.py diff --git a/plots/letsplot/histogram/histogram-basic/default.py b/plots/letsplot/histogram/histogram-basic/default.py new file mode 100644 index 0000000000..ca5a3afb99 --- /dev/null +++ b/plots/letsplot/histogram/histogram-basic/default.py @@ -0,0 +1,28 @@ +""" +histogram-basic: Basic Histogram +Library: letsplot +""" + +import numpy as np +import pandas as pd +from lets_plot import LetsPlot, aes, element_text, geom_histogram, ggplot, ggsave, ggsize, labs, theme, theme_minimal + + +LetsPlot.setup_html() + +# Data +np.random.seed(42) +data = pd.DataFrame({"value": np.random.normal(100, 15, 500)}) + +# Plot +plot = ( + ggplot(data, aes(x="value")) + + geom_histogram(bins=30, fill="#306998", color="white", alpha=0.8) + + labs(x="Value", y="Frequency", title="Basic Histogram") + + 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 x 2700 px +ggsave(plot, "plot.png", path=".", scale=3) From 6f676f1b5fdb27362c77cf3848cb59118ec7da66 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:23 +0000 Subject: [PATCH 05/16] feat(plotly): implement histogram-basic (#306) ## Summary Implements `histogram-basic` for **plotly** library. **Parent Issue:** #204 **Sub-Issue:** #223 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/plotly/histogram/histogram-basic/default.py` Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histogram/histogram-basic/default.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 plots/plotly/histogram/histogram-basic/default.py diff --git a/plots/plotly/histogram/histogram-basic/default.py b/plots/plotly/histogram/histogram-basic/default.py new file mode 100644 index 0000000000..e7f0dbc725 --- /dev/null +++ b/plots/plotly/histogram/histogram-basic/default.py @@ -0,0 +1,30 @@ +""" +histogram-basic: Basic Histogram +Library: plotly +""" + +import numpy as np +import plotly.graph_objects as go + + +# Data +np.random.seed(42) +values = np.random.normal(100, 15, 500) + +# Create figure +fig = go.Figure() +fig.add_trace(go.Histogram(x=values, marker_color="#306998", opacity=0.8, nbinsx=30)) + +# Layout +fig.update_layout( + title={"text": "Basic Histogram", "font": {"size": 20}}, + xaxis_title="Value", + yaxis_title="Frequency", + template="plotly_white", + xaxis={"title_font": {"size": 20}, "tickfont": {"size": 16}}, + yaxis={"title_font": {"size": 20}, "tickfont": {"size": 16}}, + bargap=0.05, +) + +# Save +fig.write_image("plot.png", width=1600, height=900, scale=3) From e0345e798ed1f2e4bd304d29c800bc031724787b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:33:47 +0000 Subject: [PATCH 06/16] feat(pygal): implement histogram-basic (#286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `histogram-basic` for **pygal** library. **Parent Issue:** #204 **Sub-Issue:** #252 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/pygal/histogram/histogram-basic/default.py` ## Details - Uses `pygal.Histogram()` chart type with proper bin format `(height, start, end)` - Uses numpy to calculate histogram bins from the normal distribution data - Follows the default style guide: 4800×2700px, Python Blue (#306998) - KISS implementation with no functions/classes per project guidelines Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histogram/histogram-basic/default.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 plots/pygal/histogram/histogram-basic/default.py diff --git a/plots/pygal/histogram/histogram-basic/default.py b/plots/pygal/histogram/histogram-basic/default.py new file mode 100644 index 0000000000..debf7edcdf --- /dev/null +++ b/plots/pygal/histogram/histogram-basic/default.py @@ -0,0 +1,55 @@ +""" +histogram-basic: Basic Histogram +Library: pygal +""" + +import numpy as np +import pygal +from pygal.style import Style + + +# Data +np.random.seed(42) +values = np.random.normal(100, 15, 500) # 500 values, mean=100, std=15 + +# Calculate histogram bins +counts, bin_edges = np.histogram(values, bins=20) + +# Convert to pygal histogram format: (height, start, end) +histogram_data = [(int(count), float(bin_edges[i]), float(bin_edges[i + 1])) for i, count in enumerate(counts)] + +# Custom style matching default style guide colors +custom_style = Style( + background="white", + plot_background="white", + foreground="#333333", + foreground_strong="#333333", + foreground_subtle="#666666", + opacity="0.8", + opacity_hover="0.9", + colors=("#306998",), # Python Blue + guide_stroke_color="#cccccc", + major_guide_stroke_color="#cccccc", + title_font_size=48, + label_font_size=36, + major_label_font_size=36, +) + +# Create histogram chart +chart = pygal.Histogram( + width=4800, + height=2700, + title="Basic Histogram", + x_title="Value", + y_title="Frequency", + style=custom_style, + show_legend=False, + show_y_guides=True, + show_x_guides=False, +) + +# Add histogram data +chart.add("Distribution", histogram_data) + +# Save to PNG +chart.render_to_png("plot.png") From 8649b78aee37e80c6fa68899f49de1788c50cd67 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 23:34:07 +0000 Subject: [PATCH 07/16] feat(plotnine): implement histogram-basic (#284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `histogram-basic` for **plotnine** library. **Parent Issue:** #204 **Sub-Issue:** #245 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/plotnine/histogram/histogram-basic/default.py` ## Details - Uses `geom_histogram` with 30 bins for optimal distribution visualization - Python Blue (#306998) fill color following style guide - White bin edges for clear separation - 4800×2700px output at 300 DPI (16:9 aspect ratio) - Minimal theme with appropriate typography sizes (title 20pt, axis labels 20pt, tick labels 16pt) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histogram/histogram-basic/default.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 plots/plotnine/histogram/histogram-basic/default.py diff --git a/plots/plotnine/histogram/histogram-basic/default.py b/plots/plotnine/histogram/histogram-basic/default.py new file mode 100644 index 0000000000..657ace1c28 --- /dev/null +++ b/plots/plotnine/histogram/histogram-basic/default.py @@ -0,0 +1,30 @@ +""" +histogram-basic: Basic Histogram +Library: plotnine +""" + +import numpy as np +import pandas as pd +from plotnine import aes, element_text, geom_histogram, ggplot, labs, theme, theme_minimal + + +# Data +np.random.seed(42) +data = pd.DataFrame({"value": np.random.normal(100, 15, 500)}) + +# Plot +plot = ( + ggplot(data, aes(x="value")) + + geom_histogram(bins=30, fill="#306998", color="white", alpha=0.8) + + labs(x="Value", y="Frequency", title="Basic Histogram") + + theme_minimal() + + theme( + figure_size=(16, 9), + plot_title=element_text(size=20), + axis_title=element_text(size=20), + axis_text=element_text(size=16), + ) +) + +# Save +plot.save("plot.png", dpi=300) From e7848d2d385bd030d4b60c58d3a42f70cb062fda Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 00:58:46 +0000 Subject: [PATCH 08/16] feat(plotly): implement histogram-basic (#379) ## Summary Implements `histogram-basic` for **plotly** library. **Parent Issue:** #204 **Sub-Issue:** #331 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/plotly/histogram/histogram-basic/default.py` ## Changes - Centered title for better visual appearance as per quality criteria (VQ-008) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/plotly/histogram/histogram-basic/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/plotly/histogram/histogram-basic/default.py b/plots/plotly/histogram/histogram-basic/default.py index e7f0dbc725..59d068edd4 100644 --- a/plots/plotly/histogram/histogram-basic/default.py +++ b/plots/plotly/histogram/histogram-basic/default.py @@ -17,7 +17,7 @@ # Layout fig.update_layout( - title={"text": "Basic Histogram", "font": {"size": 20}}, + title={"text": "Basic Histogram", "font": {"size": 20}, "x": 0.5, "xanchor": "center"}, xaxis_title="Value", yaxis_title="Frequency", template="plotly_white", From 1d5bf652134955a9a9151e582c2108abf5f995d9 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 01:00:28 +0000 Subject: [PATCH 09/16] feat(highcharts): implement histogram-basic (#380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements `histogram-basic` for **highcharts** library. **Parent Issue:** #204 **Sub-Issue:** #258 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/highcharts/histogram/histogram-basic/default.py` ## Details - Uses ColumnSeries with numpy.histogram to compute bins and frequencies - 4800×2700px output dimensions (16:9) - Python Blue (#306998) color scheme - Rotated axis labels (315°) for readability - X-axis: Value ranges, Y-axis: Frequency - 30 bins for the distribution Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../histogram/histogram-basic/default.py | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 plots/highcharts/histogram/histogram-basic/default.py diff --git a/plots/highcharts/histogram/histogram-basic/default.py b/plots/highcharts/histogram/histogram-basic/default.py new file mode 100644 index 0000000000..1d39589cd2 --- /dev/null +++ b/plots/highcharts/histogram/histogram-basic/default.py @@ -0,0 +1,124 @@ +""" +histogram-basic: Basic Histogram +Library: highcharts +""" + +import tempfile +import time +import urllib.request +from pathlib import Path + +import numpy as np +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 +np.random.seed(42) +values = np.random.normal(100, 15, 500) # 500 values, mean=100, std=15 + +# Calculate histogram bins +bins = 30 +counts, bin_edges = np.histogram(values, bins=bins) + +# Create bin labels (center of each bin) +bin_centers = [(bin_edges[i] + bin_edges[i + 1]) / 2 for i in range(len(counts))] +bin_labels = [f"{bin_edges[i]:.1f}-{bin_edges[i + 1]:.1f}" for i in range(len(counts))] + +# Create chart with container ID +chart = Chart(container="container") +chart.options = HighchartsOptions() + +# Chart configuration +chart.options.chart = { + "type": "column", + "width": 4800, + "height": 2700, + "backgroundColor": "#ffffff", + "spacingBottom": 120, # Add space for x-axis title +} + +# Title +chart.options.title = {"text": "Basic Histogram", "style": {"fontSize": "48px", "fontWeight": "bold"}} + +# X-axis configuration +chart.options.x_axis = { + "categories": bin_labels, + "title": {"text": "Value", "style": {"fontSize": "40px"}}, + "labels": { + "rotation": 315, # 315 degrees = -45 degrees + "style": {"fontSize": "28px"}, + "step": 3, # Show every 3rd label to avoid overlap + }, +} + +# Y-axis configuration +chart.options.y_axis = { + "title": {"text": "Frequency", "style": {"fontSize": "40px"}}, + "min": 0, + "gridLineWidth": 1, + "gridLineDashStyle": "Dot", + "gridLineColor": "rgba(0, 0, 0, 0.15)", + "labels": {"style": {"fontSize": "32px"}}, +} + +# Create series with histogram data +series = ColumnSeries() +series.data = counts.tolist() +series.name = "Frequency" +series.color = "#306998" # Python Blue +series.border_color = "white" +series.border_width = 1 + +# Plot options for histogram appearance +chart.options.plot_options = {"column": {"pointPadding": 0, "groupPadding": 0, "borderWidth": 1, "opacity": 0.8}} + +chart.add_series(series) + +# Legend (single series, hide) +chart.options.legend = {"enabled": False} + +# Credits +chart.options.credits = {"enabled": False} + +# Download Highcharts JS (required for headless Chrome) +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""" + + + + + + +
+ + +""" + +# 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") # Slightly larger to capture full chart + +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 From 1bca5febcd3ca564fab1a3458b5e300d2f76fb44 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 03:01:49 +0000 Subject: [PATCH 10/16] feat(plotly): implement histogram-basic (#414) ## Summary Implements `histogram-basic` for **plotly** library. **Parent Issue:** #206 **Sub-Issue:** #398 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/plotly/histogram/histogram-basic/default.py` ## Features - Basic histogram showing frequency distribution of 500 normally distributed data points - Uses Python Blue (#306998) color with 0.85 opacity - Scaled fonts for 4800x2700 resolution (title: 40pt, labels: 40pt, ticks: 32pt) - Added hover template for interactivity - Outputs to plot.png at 4800x2700 pixels (via scale=3 on 1600x900) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../plotly/histogram/histogram-basic/default.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/plots/plotly/histogram/histogram-basic/default.py b/plots/plotly/histogram/histogram-basic/default.py index 59d068edd4..133a0fce98 100644 --- a/plots/plotly/histogram/histogram-basic/default.py +++ b/plots/plotly/histogram/histogram-basic/default.py @@ -13,16 +13,20 @@ # Create figure fig = go.Figure() -fig.add_trace(go.Histogram(x=values, marker_color="#306998", opacity=0.8, nbinsx=30)) +fig.add_trace( + go.Histogram( + x=values, marker_color="#306998", opacity=0.85, hovertemplate="Range: %{x}
Count: %{y}" + ) +) # Layout fig.update_layout( - title={"text": "Basic Histogram", "font": {"size": 20}, "x": 0.5, "xanchor": "center"}, - xaxis_title="Value", - yaxis_title="Frequency", + title={"text": "Basic Histogram", "font": {"size": 40}, "x": 0.5, "xanchor": "center"}, + xaxis_title={"text": "Value", "font": {"size": 40}}, + yaxis_title={"text": "Frequency", "font": {"size": 40}}, template="plotly_white", - xaxis={"title_font": {"size": 20}, "tickfont": {"size": 16}}, - yaxis={"title_font": {"size": 20}, "tickfont": {"size": 16}}, + xaxis={"tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, + yaxis={"tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, bargap=0.05, ) From 99c4fc581764b07705e771f124617fe6b1c42210 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 10:26:49 +0000 Subject: [PATCH 11/16] feat(seaborn): implement histogram-basic (#464) ## Summary Implements `histogram-basic` for **seaborn** library. **Parent Issue:** #206 **Sub-Issue:** #327 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/seaborn/histplot/histogram-basic/default.py` ## Details - Uses `sns.histplot()` for creating the histogram - Python Blue (#306998) color with white edgecolor for visual clarity - 30 bins for good data distribution visualization - Proper axis labels (Value, Frequency) and title - Font sizes per style guide (20pt for labels/title, 16pt for ticks) - Subtle grid for readability - Output: 4766 x 2670 px PNG (approximately 16:9 aspect ratio) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/seaborn/histplot/histogram-basic/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/seaborn/histplot/histogram-basic/default.py b/plots/seaborn/histplot/histogram-basic/default.py index 8b665127af..37918c4162 100644 --- a/plots/seaborn/histplot/histogram-basic/default.py +++ b/plots/seaborn/histplot/histogram-basic/default.py @@ -22,7 +22,7 @@ ax.set_ylabel("Frequency", fontsize=20) ax.set_title("Basic Histogram", fontsize=20) ax.tick_params(axis="both", labelsize=16) -ax.grid(True, alpha=0.3, axis="y") +ax.grid(True, alpha=0.3, linestyle="-", linewidth=0.5) plt.tight_layout() plt.savefig("plot.png", dpi=300, bbox_inches="tight") From 48829209836393781200584e925663b634339fde Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 10:27:48 +0000 Subject: [PATCH 12/16] feat(plotly): implement histogram-basic (#466) ## Summary Implements `histogram-basic` for **plotly** library. **Parent Issue:** #206 **Sub-Issue:** #426 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/plotly/histogram/histogram-basic/default.py` ## Features - Basic histogram visualization using `go.Histogram` - Sample data: 500 values from normal distribution (mean=100, std=15) - Python Blue color palette (#306998) with white bar outlines - Proper typography for 4800x2700 output (40pt titles, 32pt labels) - Clean `plotly_white` template with subtle grid styling - 5% bar gap for visual clarity Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- .../plotly/histogram/histogram-basic/default.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/plots/plotly/histogram/histogram-basic/default.py b/plots/plotly/histogram/histogram-basic/default.py index 133a0fce98..c64ca0d2f4 100644 --- a/plots/plotly/histogram/histogram-basic/default.py +++ b/plots/plotly/histogram/histogram-basic/default.py @@ -9,24 +9,21 @@ # Data np.random.seed(42) -values = np.random.normal(100, 15, 500) +values = np.random.normal(100, 15, 500) # 500 values, mean=100, std=15 # Create figure fig = go.Figure() -fig.add_trace( - go.Histogram( - x=values, marker_color="#306998", opacity=0.85, hovertemplate="Range: %{x}
Count: %{y}" - ) -) +fig.add_trace(go.Histogram(x=values, marker={"color": "#306998", "line": {"color": "white", "width": 1}}, opacity=0.85)) # Layout fig.update_layout( title={"text": "Basic Histogram", "font": {"size": 40}, "x": 0.5, "xanchor": "center"}, - xaxis_title={"text": "Value", "font": {"size": 40}}, - yaxis_title={"text": "Frequency", "font": {"size": 40}}, + xaxis_title="Value", + yaxis_title="Frequency", template="plotly_white", - xaxis={"tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, - yaxis={"tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, + font={"size": 32}, + xaxis={"title_font": {"size": 40}, "tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, + yaxis={"title_font": {"size": 40}, "tickfont": {"size": 32}, "showgrid": True, "gridcolor": "rgba(0,0,0,0.1)"}, bargap=0.05, ) From 405c694d5fbd0253acc71de5ebcc0c78a15352b9 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 10:38:04 +0000 Subject: [PATCH 13/16] feat(matplotlib): implement histogram-basic (#477) ## Summary Implements `histogram-basic` for **matplotlib** library. **Parent Issue:** #206 **Sub-Issue:** #323 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/matplotlib/hist/histogram-basic/default.py` ## Changes - Uses pandas DataFrame structure as specified in the spec - Follows the style guide: Python Blue (#306998), 16x9 aspect ratio - Font sizes: 20pt for labels/title, 16pt for tick labels - Y-axis grid with 0.3 alpha for readability - Simple sequential code (no functions) per plot-generator rules Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/matplotlib/hist/histogram-basic/default.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plots/matplotlib/hist/histogram-basic/default.py b/plots/matplotlib/hist/histogram-basic/default.py index 7c59f56e73..ac2191c2ab 100644 --- a/plots/matplotlib/hist/histogram-basic/default.py +++ b/plots/matplotlib/hist/histogram-basic/default.py @@ -5,15 +5,16 @@ import matplotlib.pyplot as plt import numpy as np +import pandas as pd # Data np.random.seed(42) -values = np.random.normal(100, 15, 500) +data = pd.DataFrame({"value": np.random.normal(100, 15, 500)}) # Create plot fig, ax = plt.subplots(figsize=(16, 9)) -ax.hist(values, bins=30, alpha=0.8, color="#306998", edgecolor="white", linewidth=0.5) +ax.hist(data["value"], bins=30, alpha=0.8, color="#306998", edgecolor="white", linewidth=0.5) # Labels and styling ax.set_xlabel("Value", fontsize=20) From d08bd6ec1112188f4df3dd7493dac73f6e024d7f Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 20:33:21 +0000 Subject: [PATCH 14/16] feat(bokeh): implement histogram-basic (#309) ## Summary Implements `histogram-basic` for **bokeh** library. **Parent Issue:** #206 **Sub-Issue:** #228 **Base Branch:** `plot/histogram-basic` **Attempt:** 3/3 ## Implementation - `plots/bokeh/quad/histogram-basic/default.py` ## Changes 1. Basic histogram implementation using bokeh's `quad` glyph 2. Uses numpy to compute histogram bins (30 bins for good visual distribution) 3. Follows style guide with 4800x2700 px output dimensions ## Dependencies - `selenium>=4.15.0` and `webdriver-manager>=4.0.0` are already in `lib-bokeh` dependencies in `pyproject.toml` (required for `export_png`) ## CI Notes **Important:** The CI workflow needs to be updated to set up Chrome for bokeh PNG export (similar to highcharts). The fix is to update `.github/workflows/ci-plottest.yml`: ```yaml - name: Setup Chrome for Highcharts/Bokeh if: steps.detect_libs.outputs.has_plots == 'true' && (contains(steps.detect_libs.outputs.libraries, 'highcharts') || contains(steps.detect_libs.outputs.libraries, 'bokeh')) uses: browser-actions/setup-chrome@v1 with: chrome-version: stable ``` ## Verified Locally - Implementation tested locally and generates correct plot.png (4800x2700 px) - Code passes ruff format and lint checks --------- 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/quad/histogram-basic/default.py | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 plots/bokeh/quad/histogram-basic/default.py diff --git a/plots/bokeh/quad/histogram-basic/default.py b/plots/bokeh/quad/histogram-basic/default.py new file mode 100644 index 0000000000..07bb421191 --- /dev/null +++ b/plots/bokeh/quad/histogram-basic/default.py @@ -0,0 +1,51 @@ +""" +histogram-basic: Basic Histogram +Library: bokeh +""" + +import numpy as np +from bokeh.io import export_png +from bokeh.plotting import figure + + +# Data - 500 normally distributed values (mean=100, std=15) +np.random.seed(42) +values = np.random.normal(100, 15, 500) + +# Compute histogram bins +hist, edges = np.histogram(values, bins=30) + +# Create figure (4800 x 2700 px for high resolution) +p = figure(width=4800, height=2700, title="Basic Histogram", x_axis_label="Value", y_axis_label="Frequency") + +# Draw histogram using quad glyph +p.quad( + top=hist, + bottom=0, + left=edges[:-1], + right=edges[1:], + fill_color="#306998", + fill_alpha=0.7, + line_color="white", + line_width=1, +) + +# Style title +p.title.text_font_size = "20pt" +p.title.align = "center" + +# Style axis labels +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" + +# Style grid - subtle +p.xgrid.grid_line_alpha = 0.3 +p.ygrid.grid_line_alpha = 0.3 + +# Ensure y-axis starts at zero +p.y_range.start = 0 + +# Save output +export_png(p, filename="plot.png") From 7115cc14bd5c17adc09bc24baa64015cb14af937 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 20:42:12 +0000 Subject: [PATCH 15/16] feat(matplotlib): implement histogram-basic (#486) ## Summary Implements `histogram-basic` for **matplotlib** library. **Parent Issue:** #206 **Sub-Issue:** #483 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/matplotlib/hist/histogram-basic/default.py` ## Details - Uses `ax.hist()` with 30 bins for distribution visualization - Follows style guide: 4800 x 2700 px image size - Uses Python Blue (#306998) as the primary color - Includes proper axis labels, title, and subtle y-axis grid - Data: 500 normally distributed values (mean=100, std=15) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> --- plots/matplotlib/hist/histogram-basic/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/matplotlib/hist/histogram-basic/default.py b/plots/matplotlib/hist/histogram-basic/default.py index ac2191c2ab..0536e7ac87 100644 --- a/plots/matplotlib/hist/histogram-basic/default.py +++ b/plots/matplotlib/hist/histogram-basic/default.py @@ -24,4 +24,4 @@ ax.grid(True, alpha=0.3, axis="y") plt.tight_layout() -plt.savefig("plot.png", dpi=300, bbox_inches="tight") +plt.savefig("plot.png", dpi=300) From ed4be4db09d2213d7658325333170bfcd3f1073a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 20:56:58 +0000 Subject: [PATCH 16/16] feat(matplotlib): implement histogram-basic (#499) ## Summary Implements `histogram-basic` for **matplotlib** library. **Parent Issue:** #206 **Sub-Issue:** #490 **Base Branch:** `plot/histogram-basic` **Attempt:** 1/3 ## Implementation - `plots/matplotlib/hist/histogram-basic/default.py` ## Details - Uses `ax.hist()` with 30 bins for distribution visualization - Python Blue color (#306998) with white edge lines for visual clarity - Proper axis labels (Value, Frequency) and title with 20pt font size - Y-axis grid lines (alpha=0.3) for readability - Output: ~4800x2700 px image at 300 DPI with tight bounding box Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- plots/matplotlib/hist/histogram-basic/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/matplotlib/hist/histogram-basic/default.py b/plots/matplotlib/hist/histogram-basic/default.py index 0536e7ac87..ac2191c2ab 100644 --- a/plots/matplotlib/hist/histogram-basic/default.py +++ b/plots/matplotlib/hist/histogram-basic/default.py @@ -24,4 +24,4 @@ ax.grid(True, alpha=0.3, axis="y") plt.tight_layout() -plt.savefig("plot.png", dpi=300) +plt.savefig("plot.png", dpi=300, bbox_inches="tight")