From 9a90a7dc8a7fab50795eb923835659b746a191d8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 00:36:39 +0000 Subject: [PATCH] chore(plotnine): add metadata for linked-views-selection --- .../implementations/python/plotnine.py | 117 ++++++++++++++++++ .../metadata/python/plotnine.yaml | 21 ++++ 2 files changed, 138 insertions(+) create mode 100644 plots/linked-views-selection/implementations/python/plotnine.py create mode 100644 plots/linked-views-selection/metadata/python/plotnine.yaml diff --git a/plots/linked-views-selection/implementations/python/plotnine.py b/plots/linked-views-selection/implementations/python/plotnine.py new file mode 100644 index 0000000000..c11db4f7b6 --- /dev/null +++ b/plots/linked-views-selection/implementations/python/plotnine.py @@ -0,0 +1,117 @@ +"""anyplot.ai +linked-views-selection: Multiple Linked Views with Selection Sync +Library: plotnine | Python 3.13 +Quality: pending | Created: 2026-05-17 +""" + +import os +from pathlib import Path + +import numpy as np +import pandas as pd +from matplotlib import pyplot as plt +from matplotlib.patches import Patch + + +# Theme tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" + +# Okabe-Ito palette +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7"] +BRAND = OKABE_ITO[0] + +# Data +np.random.seed(42) +n = 300 +x = np.random.normal(50, 15, n) +y = x * 0.7 + np.random.normal(0, 10, n) +categories = np.random.choice(["Group A", "Group B", "Group C", "Group D"], n) +df = pd.DataFrame({"x": x, "y": y, "category": categories}) + +# Highlight one category to demonstrate linked views concept +highlighted_category = "Group A" +is_selected = df["category"] == highlighted_category + +# Plot +fig = plt.figure(figsize=(16, 9), facecolor=PAGE_BG) +gs = fig.add_gridspec(2, 3, hspace=0.3, wspace=0.3) + +ax_scatter = fig.add_subplot(gs[:, 0:2]) +ax_hist_x = fig.add_subplot(gs[0, 2]) +ax_hist_y = fig.add_subplot(gs[1, 2]) + +# Set background for all axes +ax_scatter.set_facecolor(PAGE_BG) +ax_hist_x.set_facecolor(PAGE_BG) +ax_hist_y.set_facecolor(PAGE_BG) + +# Scatter plot: full data with deemphasized points, selected highlighted +ax_scatter.scatter(df["x"], df["y"], alpha=0.15, s=100, color=INK_SOFT, edgecolors="none") +ax_scatter.scatter( + df[is_selected]["x"], df[is_selected]["y"], alpha=0.8, s=150, color=BRAND, edgecolors=PAGE_BG, linewidth=0.5 +) + +ax_scatter.set_xlabel("X Dimension", fontsize=20, color=INK) +ax_scatter.set_ylabel("Y Dimension", fontsize=20, color=INK) +ax_scatter.set_title("Scatter Plot", fontsize=18, color=INK_SOFT) +ax_scatter.tick_params(axis="both", labelsize=16, colors=INK_SOFT) +ax_scatter.spines["top"].set_visible(False) +ax_scatter.spines["right"].set_visible(False) +for s in ("left", "bottom"): + ax_scatter.spines[s].set_color(INK_SOFT) +ax_scatter.yaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK) + +# Histogram of X dimension +bins = np.linspace(df["x"].min(), df["x"].max(), 20) +ax_hist_x.hist(df["x"], bins=bins, alpha=0.15, color=INK_SOFT, edgecolor="none") +ax_hist_x.hist(df[is_selected]["x"], bins=bins, alpha=0.8, color=BRAND, edgecolor="none") +ax_hist_x.set_xlabel("X", fontsize=16, color=INK) +ax_hist_x.set_ylabel("Count", fontsize=16, color=INK) +ax_hist_x.set_title("X Distribution", fontsize=18, color=INK_SOFT) +ax_hist_x.tick_params(axis="both", labelsize=14, colors=INK_SOFT) +ax_hist_x.spines["top"].set_visible(False) +ax_hist_x.spines["right"].set_visible(False) +for s in ("left", "bottom"): + ax_hist_x.spines[s].set_color(INK_SOFT) + +# Histogram of Y dimension +bins = np.linspace(df["y"].min(), df["y"].max(), 20) +ax_hist_y.hist(df["y"], bins=bins, alpha=0.15, color=INK_SOFT, edgecolor="none") +ax_hist_y.hist(df[is_selected]["y"], bins=bins, alpha=0.8, color=BRAND, edgecolor="none") +ax_hist_y.set_xlabel("Y", fontsize=16, color=INK) +ax_hist_y.set_ylabel("Count", fontsize=16, color=INK) +ax_hist_y.set_title("Y Distribution", fontsize=18, color=INK_SOFT) +ax_hist_y.tick_params(axis="both", labelsize=14, colors=INK_SOFT) +ax_hist_y.spines["top"].set_visible(False) +ax_hist_y.spines["right"].set_visible(False) +for s in ("left", "bottom"): + ax_hist_y.spines[s].set_color(INK_SOFT) + +# Main title +fig.suptitle("linked-views-selection · plotnine · anyplot.ai", fontsize=24, fontweight="medium", color=INK, y=0.98) + +# Add legend to explain highlighting +legend_elements = [ + Patch(facecolor=INK_SOFT, alpha=0.15, label="Other data"), + Patch(facecolor=BRAND, alpha=0.8, label=f"Selected: {highlighted_category}"), +] +fig.legend( + handles=legend_elements, + loc="lower center", + fontsize=16, + frameon=True, + fancybox=False, + shadow=False, + bbox_to_anchor=(0.5, -0.02), + facecolor=ELEVATED_BG, + edgecolor=INK_SOFT, +) + +script_dir = Path(__file__).parent +output_path = script_dir / f"plot-{THEME}.png" +plt.savefig(output_path, dpi=300, bbox_inches="tight", facecolor=PAGE_BG) +plt.close() diff --git a/plots/linked-views-selection/metadata/python/plotnine.yaml b/plots/linked-views-selection/metadata/python/plotnine.yaml new file mode 100644 index 0000000000..05cb5655d5 --- /dev/null +++ b/plots/linked-views-selection/metadata/python/plotnine.yaml @@ -0,0 +1,21 @@ +# Per-library metadata for plotnine implementation of linked-views-selection +# Auto-generated by impl-generate.yml + +library: plotnine +language: python +specification_id: linked-views-selection +created: '2026-05-17T00:36:38Z' +updated: '2026-05-17T00:36:38Z' +generated_by: claude-haiku +workflow_run: 25976934580 +issue: 3344 +language_version: 3.13.13 +library_version: 0.15.4 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/linked-views-selection/python/plotnine/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/linked-views-selection/python/plotnine/plot-dark.png +preview_html_light: null +preview_html_dark: null +quality_score: null +review: + strengths: [] + weaknesses: []