Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 34 additions & 15 deletions plots/wireframe-3d-basic/implementations/python/matplotlib.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -8,14 +8,16 @@

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.ticker import MaxNLocator


# Theme tokens
THEME = os.getenv("ANYPLOT_THEME", "light")
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)
Expand All @@ -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)
Expand All @@ -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)
231 changes: 11 additions & 220 deletions plots/wireframe-3d-basic/metadata/python/matplotlib.yaml
Original file line number Diff line number Diff line change
@@ -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: []