From 5a262c6ed1330c2510731947957506818ff90e28 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Jan 2026 21:31:12 +0000 Subject: [PATCH 1/3] feat(letsplot): implement contour-decision-boundary --- .../implementations/letsplot.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 plots/contour-decision-boundary/implementations/letsplot.py diff --git a/plots/contour-decision-boundary/implementations/letsplot.py b/plots/contour-decision-boundary/implementations/letsplot.py new file mode 100644 index 0000000000..8a7317bb7d --- /dev/null +++ b/plots/contour-decision-boundary/implementations/letsplot.py @@ -0,0 +1,89 @@ +"""pyplots.ai +contour-decision-boundary: Decision Boundary Classifier Visualization +Library: lets-plot | Python 3.13 +Quality: pending | Created: 2026-01-01 +""" + +import numpy as np +import pandas as pd +from lets_plot import ( + LetsPlot, + aes, + element_text, + geom_point, + geom_tile, + ggplot, + ggsave, + ggsize, + labs, + scale_color_manual, + scale_fill_manual, + scale_shape_manual, + theme, + theme_minimal, +) +from sklearn.datasets import make_moons +from sklearn.neighbors import KNeighborsClassifier + + +LetsPlot.setup_html() + +# Data - Create synthetic classification data +np.random.seed(42) +X, y = make_moons(n_samples=200, noise=0.25, random_state=42) + +# Train a KNN classifier +classifier = KNeighborsClassifier(n_neighbors=5) +classifier.fit(X, y) + +# Create mesh grid for decision boundary +h = 0.02 # Step size +x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5 +y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5 +xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) + +# Predict class for each point in mesh +Z = classifier.predict(np.c_[xx.ravel(), yy.ravel()]) +Z = Z.reshape(xx.shape) + +# Create DataFrame for mesh grid +mesh_df = pd.DataFrame({"X1": xx.ravel(), "X2": yy.ravel(), "Predicted": Z.ravel().astype(str)}) + +# Create DataFrame for training points +train_df = pd.DataFrame({"X1": X[:, 0], "X2": X[:, 1], "Class": y.astype(str)}) + +# Add classification result (correct/incorrect) for training points +predictions = classifier.predict(X) +train_df["Correct"] = np.where(predictions == y, "Correct", "Incorrect") + +# Plot - Decision boundary with training points +plot = ( + ggplot() + # Decision regions as filled contour using tiles + + geom_tile(aes(x="X1", y="X2", fill="Predicted"), data=mesh_df, alpha=0.4) + # Training points + + geom_point(aes(x="X1", y="X2", color="Class", shape="Correct"), data=train_df, size=5, stroke=1.5) + # Color scales + + scale_fill_manual(values=["#306998", "#FFD43B"], name="Predicted Class") + + scale_color_manual(values=["#306998", "#FFD43B"], name="True Class") + + scale_shape_manual(values=[16, 4], name="Classification") # Circle for correct, X for incorrect + # Labels + + labs(title="contour-decision-boundary · letsplot · pyplots.ai", x="Feature X1", y="Feature X2") + # Theme + + theme_minimal() + + theme( + plot_title=element_text(size=24), + axis_title=element_text(size=20), + axis_text=element_text(size=16), + legend_title=element_text(size=18), + legend_text=element_text(size=14), + legend_position="right", + ) + + ggsize(1600, 900) +) + +# Save - use path parameter to specify exact location +ggsave(plot, filename="plot.png", path=".", scale=3) + +# Save HTML for interactive version +ggsave(plot, filename="plot.html", path=".") From fc5d4869d2a7bb397f094c988d3ee8b521a88dd0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Jan 2026 21:31:35 +0000 Subject: [PATCH 2/3] chore(letsplot): add metadata for contour-decision-boundary --- .../metadata/letsplot.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plots/contour-decision-boundary/metadata/letsplot.yaml diff --git a/plots/contour-decision-boundary/metadata/letsplot.yaml b/plots/contour-decision-boundary/metadata/letsplot.yaml new file mode 100644 index 0000000000..f56a9e61a9 --- /dev/null +++ b/plots/contour-decision-boundary/metadata/letsplot.yaml @@ -0,0 +1,19 @@ +# Per-library metadata for letsplot implementation of contour-decision-boundary +# Auto-generated by impl-generate.yml + +library: letsplot +specification_id: contour-decision-boundary +created: '2026-01-01T21:31:34Z' +updated: '2026-01-01T21:31:34Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20645829576 +issue: 2921 +python_version: 3.13.11 +library_version: 4.8.2 +preview_url: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot_thumb.png +preview_html: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot.html +quality_score: null +review: + strengths: [] + weaknesses: [] From 711c2b6293734a91110d4e3bddfa2347a0b1d36a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Jan 2026 21:33:50 +0000 Subject: [PATCH 3/3] chore(letsplot): update quality score 91 and review feedback for contour-decision-boundary --- .../implementations/letsplot.py | 6 ++--- .../metadata/letsplot.yaml | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/plots/contour-decision-boundary/implementations/letsplot.py b/plots/contour-decision-boundary/implementations/letsplot.py index 8a7317bb7d..b67a0a8879 100644 --- a/plots/contour-decision-boundary/implementations/letsplot.py +++ b/plots/contour-decision-boundary/implementations/letsplot.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai contour-decision-boundary: Decision Boundary Classifier Visualization -Library: lets-plot | Python 3.13 -Quality: pending | Created: 2026-01-01 +Library: letsplot 4.8.2 | Python 3.13.11 +Quality: 91/100 | Created: 2026-01-01 """ import numpy as np diff --git a/plots/contour-decision-boundary/metadata/letsplot.yaml b/plots/contour-decision-boundary/metadata/letsplot.yaml index f56a9e61a9..df22f358b0 100644 --- a/plots/contour-decision-boundary/metadata/letsplot.yaml +++ b/plots/contour-decision-boundary/metadata/letsplot.yaml @@ -1,10 +1,7 @@ -# Per-library metadata for letsplot implementation of contour-decision-boundary -# Auto-generated by impl-generate.yml - library: letsplot specification_id: contour-decision-boundary created: '2026-01-01T21:31:34Z' -updated: '2026-01-01T21:31:34Z' +updated: '2026-01-01T21:33:49Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20645829576 issue: 2921 @@ -13,7 +10,20 @@ library_version: 4.8.2 preview_url: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot_thumb.png preview_html: https://storage.googleapis.com/pyplots-images/plots/contour-decision-boundary/letsplot/plot.html -quality_score: null +quality_score: 91 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent visual representation of the decision boundary using geom_tile for filled + regions + - Clear distinction between correctly and incorrectly classified points using shape + encoding + - Appropriate use of lets-plot grammar of graphics with proper layering (background + regions + foreground points) + - 'Good color scheme with Python colors (#306998 blue, #FFD43B yellow) that is colorblind-accessible' + - 'Comprehensive legend system showing all three aspects: predicted class, true + class, and classification accuracy' + weaknesses: + - Three separate legends consume significant horizontal space; could potentially + be consolidated + - Axis labels lack meaningful domain context (just Feature X1/X2 since using synthetic + data)