diff --git a/plots/wireframe-3d-basic/implementations/python/matplotlib.py b/plots/wireframe-3d-basic/implementations/python/matplotlib.py index 3beff57553..aa3c901d8a 100644 --- a/plots/wireframe-3d-basic/implementations/python/matplotlib.py +++ b/plots/wireframe-3d-basic/implementations/python/matplotlib.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai wireframe-3d-basic: Basic 3D Wireframe Plot Library: matplotlib 3.10.9 | Python 3.13.13 Quality: 91/100 | Updated: 2026-05-06 @@ -8,6 +8,8 @@ import matplotlib.pyplot as plt import numpy as np +from matplotlib.colors import LinearSegmentedColormap +from matplotlib.ticker import MaxNLocator # Theme tokens @@ -15,7 +17,7 @@ PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" INK = "#1A1A17" if THEME == "light" else "#F0EFE8" INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" -BRAND = "#009E73" # Okabe-Ito position 1 +BRAND = "#009E73" # Imprint palette position 1 # Data - ripple function z = sin(sqrt(x^2 + y^2)) np.random.seed(42) @@ -25,25 +27,42 @@ R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -# Create 3D plot -fig = plt.figure(figsize=(16, 9), facecolor=PAGE_BG) +# Imprint sequential colormap, used only for the floor contour echo below +imprint_seq = LinearSegmentedColormap.from_list("imprint_seq", ["#009E73", "#4467A3"]) + +# Create 3D plot (3200x1800 px) +fig = plt.figure(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG) ax = fig.add_subplot(111, projection="3d") +ax.set_facecolor(PAGE_BG) + +# Ripple wireframe in brand green — the single consistent-color primary series. +# rcount/ccount subsample the 40x40 data grid down to 25x25 drawn lines so the +# mesh stays crisp instead of moire-ing into a dense hairball at this viewing angle. +ax.plot_wireframe(X, Y, Z, color=BRAND, linewidth=1.6, alpha=0.85, rcount=25, ccount=25) -# Plot wireframe -ax.plot_wireframe(X, Y, Z, color=BRAND, linewidth=2.5, alpha=0.85) +# Contour projection on the floor plane echoes the ripple's height structure +# as a topographic footprint, giving a second, easier-to-read view of the +# same Z data without competing with the wireframe's brand-green identity +z_floor = Z.min() - 0.6 +ax.contour(X, Y, Z, zdir="z", offset=z_floor, levels=10, cmap=imprint_seq, linewidths=1.0, alpha=0.55) +ax.set_zlim(z_floor, Z.max() + 0.15) # Set viewing angle (elevation 30, azimuth 45 as per spec) ax.view_init(elev=30, azim=45) # Labels and styling -ax.set_xlabel("Distance from Center (X)", fontsize=20, labelpad=15, color=INK) -ax.set_ylabel("Distance from Center (Y)", fontsize=20, labelpad=15, color=INK) -ax.set_zlabel("Amplitude (Z)", fontsize=20, labelpad=15, color=INK) -ax.set_title("wireframe-3d-basic · matplotlib · anyplot.ai", fontsize=24, pad=20, color=INK) +ax.set_xlabel("Distance from Center (X)", fontsize=12, labelpad=10, color=INK) +ax.set_ylabel("Distance from Center (Y)", fontsize=12, labelpad=10, color=INK) +ax.set_zlabel("Amplitude (Z)", fontsize=12, labelpad=8, color=INK) +ax.set_title("wireframe-3d-basic · matplotlib · anyplot.ai", fontsize=15, fontweight="medium", pad=14, color=INK) -# Tick parameters -ax.tick_params(axis="both", labelsize=16, colors=INK_SOFT) -ax.tick_params(axis="z", labelsize=16, colors=INK_SOFT) +# Tick parameters — fewer, cleaner ticks with a compact numeric format +ax.xaxis.set_major_locator(MaxNLocator(5)) +ax.yaxis.set_major_locator(MaxNLocator(5)) +ax.zaxis.set_major_locator(MaxNLocator(5)) +ax.zaxis.set_major_formatter("{x:.1f}") +ax.tick_params(axis="both", labelsize=10, colors=INK_SOFT) +ax.tick_params(axis="z", labelsize=10, colors=INK_SOFT) # Theme-adaptive panes and grid ax.xaxis.pane.set_facecolor(PAGE_BG) @@ -52,7 +71,7 @@ ax.xaxis.pane.set_edgecolor(INK_SOFT) ax.yaxis.pane.set_edgecolor(INK_SOFT) ax.zaxis.pane.set_edgecolor(INK_SOFT) -ax.grid(True, alpha=0.15, linestyle="-", color=INK_SOFT, linewidth=0.8) +ax.grid(True, alpha=0.15, linestyle="-", color=INK_SOFT, linewidth=0.6) plt.tight_layout() -plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG) +plt.savefig(f"plot-{THEME}.png", dpi=400, facecolor=PAGE_BG) # bbox_inches MUST stay default (None) diff --git a/plots/wireframe-3d-basic/metadata/python/matplotlib.yaml b/plots/wireframe-3d-basic/metadata/python/matplotlib.yaml index 59af8bc262..9896e04e0d 100644 --- a/plots/wireframe-3d-basic/metadata/python/matplotlib.yaml +++ b/plots/wireframe-3d-basic/metadata/python/matplotlib.yaml @@ -1,230 +1,21 @@ +# Per-library metadata for matplotlib implementation of wireframe-3d-basic +# Auto-generated by impl-generate.yml + library: matplotlib language: python specification_id: wireframe-3d-basic created: '2025-12-24T09:50:15Z' -updated: '2026-05-06T05:30:37Z' -generated_by: claude-haiku -workflow_run: 25417742290 +updated: '2026-08-04T18:15:44Z' +generated_by: claude-sonnet +workflow_run: 30937249944 issue: 1015 -python_version: 3.13.13 -library_version: 3.10.9 +language_version: 3.13.14 +library_version: 3.11.1 preview_url_light: https://storage.googleapis.com/anyplot-images/plots/wireframe-3d-basic/python/matplotlib/plot-light.png preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/wireframe-3d-basic/python/matplotlib/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: 91 +quality_score: null review: - strengths: - - Perfect theme adaptation — both light and dark renders fully readable with proper - contrast - - 'Correct palette compliance — brand green #009E73 used consistently; backgrounds - match spec' - - Full spec coverage — all required features implemented (grid lines, viewing angle, - axis labels) - - Clean KISS implementation with explicit theme tokens and proper reproducibility - seeding - - Good data choice — ripple function demonstrates wireframe topology clearly - weaknesses: - - Design Excellence below maximum — generic visual refinement; could benefit from - additional polishing beyond defaults - image_description: |- - Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) with proper contrast — not pure white - Chrome: Title "wireframe-3d-basic · matplotlib · anyplot.ai" in dark ink (#1A1A17) at 24pt; axis labels "Distance from Center (X/Y)", "Amplitude (Z)" in dark ink at 20pt; tick labels in INK_SOFT (#4A4A44) at 16pt — all clearly readable against light background - Data: Wireframe mesh in brand green (#009E73) with linewidth 2.5, alpha 0.85; 40×40 grid density; 3D panes match background color with INK_SOFT edges; grid lines subtle (alpha=0.15) but visible - Legibility verdict: PASS — all text readable, no light-on-light issues, proper contrast throughout - - Dark render (plot-dark.png): - Background: Warm near-black (#1A1A17) with proper contrast — not pure black - Chrome: Title in light text (#F0EFE8) at 24pt; axis labels in light text at 20pt; tick labels in INK_SOFT (#B8B7B0 in dark mode) at 16pt — all clearly readable against dark background, no dark-on-dark failures - Data: Wireframe mesh in brand green (#009E73) — visually identical to light render, confirming theme-independent data color; 3D panes match dark background with light edges; grid lines subtle but visible - Legibility verdict: PASS — all text readable, no dark-on-dark failures, proper contrast maintained across all elements, perfect theme adaptation - criteria_checklist: - visual_quality: - score: 30 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 8 - max: 8 - passed: true - comment: All text explicitly sized (title 24pt, labels 20pt, ticks 16pt) and - colored; readable in both themes - - id: VQ-02 - name: No Overlap - score: 6 - max: 6 - passed: true - comment: Clean spacing with labelpad=15 and title pad=20; no overlapping elements - - id: VQ-03 - name: Element Visibility - score: 6 - max: 6 - passed: true - comment: 40×40 grid at optimal density; wireframe lines visible at linewidth - 2.5 - - id: VQ-04 - name: Color Accessibility - score: 2 - max: 2 - passed: true - comment: 'Brand green #009E73 (Okabe-Ito position 1) is CVD-safe with adequate - contrast' - - id: VQ-05 - name: Layout & Canvas - score: 4 - max: 4 - passed: true - comment: 16:9 aspect fills canvas well; 3D projection properly framed; nothing - cut off - - id: VQ-06 - name: Axis Labels & Title - score: 2 - max: 2 - passed: true - comment: Title includes spec-id, library, site; axes labeled with units - - id: VQ-07 - name: Palette Compliance - score: 2 - max: 2 - passed: true - comment: 'Backgrounds #FAF8F1 (light) / #1A1A17 (dark); data color #009E73 - in both; chrome tokens properly applied' - design_excellence: - score: 12 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 5 - max: 8 - passed: false - comment: Intentional choices show design thought but lacks exceptional polish - - id: DE-02 - name: Visual Refinement - score: 3 - max: 6 - passed: false - comment: Properly themed panes and subtle grid; minimal customization beyond - defaults - - id: DE-03 - name: Data Storytelling - score: 4 - max: 6 - passed: true - comment: Ripple function demonstrates topology; viewing angle creates clear - focal point - spec_compliance: - score: 15 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: 3D wireframe using ax.plot_wireframe() correctly - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: Grid lines, consistent color, proper angle, all axes labeled - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: X, Y, Z correctly mapped; 40×40 grid; z = sin(sqrt(x² + y²)) ripple - function - - id: SC-04 - name: Title & Legend - score: 3 - max: 3 - passed: true - comment: Proper title format; no legend needed for single-series - data_quality: - score: 15 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 6 - max: 6 - passed: true - comment: Ripple surface fully displayed; all wireframe aspects visible - - id: DQ-02 - name: Realistic Context - score: 5 - max: 5 - passed: true - comment: Mathematically appropriate ripple function; neutral and educational - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: X/Y ∈ [-6, 6]; Z ∈ [-1, 1]; 40×40 resolution optimal - code_quality: - score: 10 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: No unnecessary functions or classes; straightforward - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: np.random.seed(42) ensures deterministic output - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: Only os, matplotlib.pyplot, numpy; all used - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: No fake interactivity; clean theme handling - - id: CQ-05 - name: Output & API - score: 1 - max: 1 - passed: true - comment: Saves as plot-{THEME}.png with correct DPI and facecolor - library_mastery: - score: 9 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 5 - max: 5 - passed: true - comment: ax.plot_wireframe() idiomatic; proper 3D projection and axes config - - id: LM-02 - name: Distinctive Features - score: 4 - max: 5 - passed: true - comment: Good use of 3D projection and pane customization; theme-adaptive - styling - verdict: APPROVED -impl_tags: - dependencies: [] - techniques: - - 3d-projection - patterns: - - data-generation - - matrix-construction - dataprep: [] - styling: - - grid-styling + strengths: [] + weaknesses: []